Manually Authenticating Users

Without a kit, a login is one Auth call. The Getting Started with Laravel skeleton gets this controller, a Blade form at GET /login (the route auth sends guests to), and a /whoami route that returns the start of the session ID, Auth::check(), Auth::user()?->email and Auth::viaRemember().

app/Http/Controllers/LoginController.php, the store action behind POST /loginPHP
public function store(Request $request): RedirectResponse
{
    $credentials = $request->validate([
        'email' => ['required', 'email'],
        'password' => ['required', 'string'],
    ]);
    if (! Auth::attempt($credentials, $request->boolean('remember'))) {
        return back()->withErrors(['email' => __('auth.failed')])->onlyInput('email');
    }
    $request->session()->regenerate();
    return redirect()->intended('/account');
}
A protected page, then a login (helpers from Section 5.14.5)Shell
curl -s $J -o /dev/null -w "$W" $B/account
T=$(tok /login); curl -s $J $B/whoami; echo
curl -s $J -o /dev/null -w "$W" -d "_token=$T&$P=correct-horse-9" $B/login
curl -s $J $B/whoami; echo; curl -s $J $B/account; echo
Output
302 http://127.0.0.1:8314/login
{"session":"eVtss69m","check":false,"user":null,"via_remember":false}
302 http://127.0.0.1:8314/account
{"session":"DObhFOQB","check":true,"user":"ada@example.com","via_remember":false}
Hello, Ada

attempt() turns every credential except password into a where clause, checks the password, rehashes it if needed and calls login(), inside a Timebox so that a missing user and a wrong password take equally long. intended() returned Ada to the URL auth had saved. The session ID changed because SessionGuard::login() itself calls regenerate(true), which defeats session fixation. Auth::login($user) skips the password, Auth::once() authenticates one request without a session, and Auth::attemptWhen($credentials, fn ($u) => ! $u->is_banned) adds a check.