Shouldn't the [auth:sanctum] middleware reject requests that have only web authentication?

28 views Asked by At

I have a test that is failing unexpectedly, and I'm wondering if there's something obvious I'm missing. Basically, I want to test an API endpoint returns the appropriate responses depending on common case scenarios (unauthenticated user, forbidden actions, invalid data, valid data, etc).

I am using sanctum and (to me), it does not make sense for this api endpoint to work with other forms of authentication. However, this test is failing.

PostControllerTest

public function test_should_return_401()
{
    $user = User::factory()->create();
    
    $response = $this->actingAs($user, 'web')->postJson(route('posts.store'), []);

    $response->assertStatus(401);
}

I have checked the route is using the auth:sanctum middleware.

routes/api.php

Route::middleware(['auth:sanctum'])->group(function () {
    Route::apiResource('posts');
});

And there does not seem to be anything out of the ordinary in the default middleware...

Middleware/Kernel

protected $middlewareGroups = [
    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

...or the service provider.

RouteServiceProvider

public function boot()
{
    $this->configureRateLimiting();

    $this->routes(function () {
        Route::middleware('api')
            ->prefix('api')
            ->group(base_path('routes/api.php'));
    });
}

Am I missing something or is this expected behavior?

1

There are 1 answers

1
N69S On

It would not fail since you can use the same middleware auth:sanctum for both web and api call, and as it is written in the Docs

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.

You may be wondering why we suggest that you authenticate the routes within your application's routes/web.php file using the sanctum guard. Remember, Sanctum will first attempt to authenticate incoming requests using Laravel's typical session authentication cookie. If that cookie is not present then Sanctum will attempt to authenticate the request using a token in the request's Authorization header.

You can limit out the API routes to only stateless request by commenting out the middleware

// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,