Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

t0berius's avatar
Level 13

laravel sanctum and default `auth:web`

Just because my understanding of the sanctum package seems to be wrong in some places:

1.) I thought by reading the config of sanctum it will use the default

/*
|--------------------------------------------------------------------------
| Sanctum Guards
|--------------------------------------------------------------------------
|
| This array contains the authentication guards that will be checked when
| Sanctum is trying to authenticate a request. If none of these guards
| are able to authenticate the request, Sanctum will use the bearer
| token that's present on an incoming request for authentication.
|
*/

'guard' => ['web'],

web guard, meaning users which are already logged in on the website (using default laravel authentication) would be able to view routes, protected by auth:sanctum? In my tests the users remain unauthenticated and won't get access to the routes, even if they are autenticated by laravel, is there some kind of missunderstanding?

2.) How to achieve it to be able to access a route, either by passing a bearerToken or just by being authenticated by laravel (using default session cookie)? Either using Route::middleware(['auth:sanctum', 'auth:web']) wasn't able to do the trick.

3.) What is the EnsureFrontendRequestsAreStateful middleware being used for?

    'api' => [
        //\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,

It was commented out so I leave it as it is.

0 likes
11 replies
t0berius's avatar
Level 13

@snapey

requested route is running under /api*, hope this answes your question :)

Snapey's avatar

so api routes are stateless (no session). You can introduce the middleware if you want it to be stateful (point 3).

So you need to send bearer token with every request (point 2)

If you dont send Bearer token then, yes your requests are unauthenticated since session cookies, although sent by client are not inspected by api routes. (point 1)

If you want to use session authentication then just put your routes (for your ajax calls) in the web routes file and save your API routes for third party connections to your site.

t0berius's avatar
Level 13

@snapey

now I understand what EnsureFrontendRequestsAreStateful is being used for.

When I edit my api like this:

    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:sanctum_token_limit',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

and I protect the routes like:

Route::middleware(['auth:web'])->group(function () {

I get redirected to the the dashboard route all the time when I request the api route:

public const HOME = '/user/dashboard';

As soon as I remove the middleware

Route::middleware([])->group(function () {

I'm able to get results from the requested api controller.

Just want to do this step by step, so first the auth:web middleware and after this the auth:sanctum middleware.

In the end I would like to view API results either by being "logged in" or when sending a bearer Token (as being used in other applications).

puklipo's avatar

When talking about Sanctum, it is necessary to specify whether it is "SPA authentication" or "API token authentication".

The actual entity of auth:sanctum is this class. https://github.com/laravel/sanctum/blob/4.x/src/Guard.php

First, it checks if the session has already authenticated.

Next, it checks the token.

This single guard supports "SPA authentication" and "API token authentication".

The only way to truly understand Sanctum is to read the code.

t0berius's avatar
Level 13

@puklipo as you can see above I removed the auth:sanctum middleware at the moment.

So you suggest to use first auth:web and then auth:sanctum inside the middleware() definition of the group?

I would like to use Sanctum ONLY for bearer token authentication.

Snapey's avatar

My understanding is that sanctum does both

From the docs:

To protect routes so that all incoming requests must be authenticated, you should attach the sanctum authentication guard to your protected routes within your routes/web.php and routes/api.php route files. This guard will ensure that incoming requests are authenticated as either stateful, cookie authenticated requests or contain a valid API token header if the request is from a third party.

2 likes
t0berius's avatar
Level 13

@snapey that's how I understood the doc too, so auth:sanctum as middleware should be all that's required to allow access to api* routes.

Maybe somebody has more deep sanctum knowledge?

@puklipo any idea why I get redirected all the time when I'm already logged in (using default laravel authentication)?

t0berius's avatar
t0berius
OP
Best Answer
Level 13

@Snapey here the full breakdown:

https://stackoverflow.com/a/78884786/16222896

it turns out sanctums guard is just for the own implementation of cookies when using sanctum, To protect a route by either bearer token (sanctum) or the default laravel authentication (auth:web) you would need to create a custom middleware for.

Thanks for your help, you're a helpful member of laracasts!

LaryAI's avatar
Level 58

Sure, let's address each part of your question regarding Laravel Sanctum and the default auth:web guard.

1. Understanding Sanctum Guard Configuration

The guard configuration in Sanctum is used to specify which authentication guards should be checked when Sanctum is trying to authenticate a request. By default, it is set to ['web'], which means it will use the web guard for authentication.

However, if users authenticated via the web guard are not able to access routes protected by auth:sanctum, it might be due to how the authentication is being handled in your application. Ensure that the session is properly maintained and that the user is indeed authenticated.

2. Accessing Routes with Bearer Token or Session Cookie

To allow access to routes either by passing a bearerToken or by being authenticated via the default Laravel session cookie, you can use the auth:sanctum middleware. This middleware will check for both the session cookie and the bearer token.

Here is an example of how you can set up your routes:

use Illuminate\Support\Facades\Route;

Route::middleware(['auth:sanctum'])->group(function () {
    Route::get('/protected-route', function () {
        return response()->json(['message' => 'You are authenticated']);
    });
});

In this setup, the auth:sanctum middleware will check if the user is authenticated either via the session cookie or a bearer token.

3. EnsureFrontendRequestsAreStateful Middleware

The EnsureFrontendRequestsAreStateful middleware is used to ensure that requests from your frontend (SPA) are treated as stateful. This is particularly useful when you are using Sanctum to authenticate a SPA that is served from the same domain or subdomain as your API.

When this middleware is enabled, it will:

  • Ensure that the session cookie is sent with the request.
  • Ensure that the CSRF token is validated.

Here is how you can enable it in your api middleware group:

use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;

'api' => [
    EnsureFrontendRequestsAreStateful::class,
    // other middlewares...
],

Summary

  1. Ensure that the web guard is properly configured and that the user is authenticated.
  2. Use the auth:sanctum middleware to protect routes and allow access via session cookie or bearer token.
  3. Enable the EnsureFrontendRequestsAreStateful middleware if you are using Sanctum to authenticate a SPA.

By following these steps, you should be able to achieve the desired authentication behavior in your Laravel application.

Please or to participate in this conversation.