← Laravel: requests, data and application decisions
07 / 10 · 65 MIN

Authentication, authorization and sessions

Separate identity, session, resource authorization and request-forgery protection. Interpret guards, policies and the origin/token behavior in Laravel 13’s documented contract.

Guard, provider and permission

The guard defines how a request is authenticated, for example through a session and cookies. The provider defines how users are retrieved from persistent storage. In auth:admin, admin identifies a guards entry in config/auth.php; it does not automatically assign an administrative role.

To diagnose unexpected identities, reconcile effective guard and provider with retrieved users. Then check permission for the action on the resource. Changing the identity mechanism does not itself implement that business rule.

Manual login and session renewal

Auth::attempt receives credentials and verifies the password against the stored value. Do not pre-hash the received password before passing it to attempt. In the documented manual flow, success is followed by session()->regenerate() before redirecting to address session fixation.

A logged_in=true field or a new redirect destination does not renew the identifier. Distinguish the manual example from a starter kit already implementing the flow; establish existing behavior before duplicating logic.

Logout and residual state

Auth::logout removes authentication information from the session, but the recommended sequence includes invalidating the session and regenerating the CSRF token. Redirecting to login only changes navigation; it is not evidence that all previous transient data was removed.

Define which state must end in the current session and inspect the complete contract. This sequence must not be presented as automatic revocation of every personal token, every session on other devices or effects already accepted by the application.

Decide or continue in a policy

In a policy before hook where the ability method exists, true allows and false denies before that method. Return null when the decision should continue to update or another ability. User type also matters: by default, guests do not reach the rule; an optional argument allows the policy to evaluate them.

Nullability does not grant access. A public-article policy must inspect publication state and explicitly handle users without a session while retaining protection of private articles.

Enforce the rule at the endpoint

The can middleware receives the ability and resource parameter, such as can:update,invoice. Once binding succeeds, an ordinary policy denial prevents the action and results in 403 unless customized. The @can directive controls what the view displays; a client can send the request without using that button.

Retain server-side enforcement for the actual action. Conceptual access checks should include a valid identity acting on another account’s resource, not only a logged-out user or hidden form.

Origin and token in Laravel 13

PreventRequestForgery in the default web group first checks request origin through Sec-Fetch-Site. When same-origin verification passes, the layer allows continuation without validating the token; otherwise, default configuration falls back to token validation. originOnly disables that fallback and denies with 403 when origin verification fails, even if a valid token exists.

Consider HTTPS, configuration and any exclusions when diagnosing. Retain @csrf in forms intended for the token flow. Passing this protection neither authenticates nor authorizes the action.

First-party SPA and token ability

In Sanctum’s first-party SPA authentication flow, tokenCan returns true for authenticated requests initiated by the first-party interface. This behavior permits a uniform check call, but it does not prove that a persisted personal token with that ability exists or that the user may modify any invoice.

Combine ability analysis with the identity-and-resource policy. If changing an ID permits acting on another account, hiding the ID or repeating tokenCan does not resolve the missing access decision.

<?php
// Route excerpt: imports, InvoiceController and policy registration omitted.
Route::patch('/invoices/{invoice}', [InvoiceController::class, 'update'])
    ->middleware(['auth', 'can:update,invoice']);

// InvoicePolicy excerpt: all users follow the same account/edit rule here.
public function update(User $user, Invoice $invoice): bool
{
    return $user->account_id === $invoice->account_id
        && $user->can_edit_invoices;
}

// Separate logout controller excerpt for the current web session.
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
IN PRACTICE

Binding resolves the invoice and can:update,invoice applies the policy before the action. The rule illustrates account membership and editing permission; it assumes consistent ID types, appropriate casts and policy registration. Input validation and permitted update fields still need controller implementation.

The logout fragment is separate and limited to the current web session. These are interpretation excerpts; execution is not requested and a complete application is not supplied.

Common pitfalls

Interpreting auth:admin as an administrative role; returning false from before when continuation was intended; making the user nullable while omitting the access rule; treating tokenCan as permission on every resource; always predicting 419 when _token is missing.

Related topics: Routes, binding and middleware · Validation and request contracts · Blade, output and API resources

Take this idea with you

Each control answers a different question: who is authenticated, which session remains valid, which action is allowed on this resource, and whether the request passes forgery protection. Establish effective configuration before inferring results from a name or a single HTTP status.

Create account

Reference: Guards, providers and permissions · Laravel 13.x; PHP 8.3+