Authentication

Authentication is about knowing who is making a request. Fast gives you a small, focused auth layer built on top of sessions: you enable a user provider, and then auth() handles logging users in and out and telling you who is currently signed in.

Enabling auth

Auth needs a user provider, which is the thing that knows how to look users up and verify their passwords. Fast ships a database-backed provider that reads from a table:

use Fast\Auth\DatabaseUserProvider;

use_auth(new DatabaseUserProvider('users'));

That points auth at a users table. You can supply any object implementing Fast\Auth\UserProvider if you need custom lookup logic, but the database provider covers the common case.

Logging a user in

The typical login flow validates the input, calls attempt() with the credentials, and redirects on success:

post('/login', function (): Fast\Http\Response {
	$data = validate(request()->form(), [
		'email' => 'required|email',
		'password' => 'required|string',
	]);

	if (!auth()->attempt($data)) {
		return json(['error' => 'invalid credentials'], 422);
	}

	return redirect('/dashboard');
});

attempt() looks up the user by the given credentials, verifies the password, and if everything checks out, logs them in and returns true. If not, it returns false and nothing changes.

The auth API

auth() exposes everything you need to work with the current user:

auth()->attempt($credentials);   // verify and log in; returns bool
auth()->login($user);            // log in a user object directly
auth()->logout();                // end the session's login
auth()->user();                  // the current user, or null
auth()->check();                 // true if someone is logged in
auth()->guest();                 // true if nobody is logged in
auth()->id();                    // the current user's id, or null

A simple gate in a handler looks like this:

get('/dashboard', function (): string {
	if (auth()->guest()) {
		return redirect('/login');
	}

	return render('dashboard', ['user' => auth()->user()]);
});

Passwords

Never store or compare passwords in plain text. Fast provides Fast\Auth\Hash for hashing on registration and verifying on login, and the database provider uses it under the hood:

use Fast\Auth\Hash;

$hash = Hash::make($plainPassword);   // store this
Hash::verify($plainPassword, $hash);  // returns true on a match

Session fixation defense

A subtle but important detail: logging in and out regenerates the session id automatically. This defends against session fixation, where an attacker who knows a victim's pre-login session id could otherwise ride it after they authenticate. Because Fast rotates the id at the login boundary, that attack does not work.

If your app uses a database-backed user provider, resolve auth()->user() before opening a database transaction. Its first lookup is lazy, and it cannot open a second database checkout from inside a transaction. Fetch the user first, then start the transaction.

That rounds out security. Next we get into Fast's most distinctive feature set: real-time, starting with Live Components.