'How to log out from Laravel via Sanctum SPA
I have a Vue.js SPA (app.example.com) that communicates with a backend Laravel application (accounts.example.com). Authentication is handled by the Laravel application - if an unauthenticated user visits the SPA, they are redirected to the Laravel app to log in and then redirected back to the SPA.
The Laravel application has a LoginController that is using Laravel's built-in Illuminate\Foundation\Auth\AuthenticatesUsers trait. Logging in works perfectly.
The problem I have is with logging out - I have a "Log out" button in the SPA that needs to log out the Laravel session.
In order to prevent denial-of-service via CSRF, Laravel's default logout route (in routes/web.php -- Route::post('logout', [LoginController::class, 'logout'])) only accepts POST requests, not GET requests. Additionally, the logout POST must contain the CSRF token in the _token field.
By default, I don't have access to the raw CSRF token in the SPA, only the encrypted version provided by /sanctum/csrf-cookie, so I can't just create a form and have Vue.js submit it. I also can't use axios to do the logout for the same reason.
I tried to add another route (in routes/api.php) like this so the same logout function will be called but the api middleware group is applied instead of the web middleware group:
Route::post('/logout', [\App\Http\Controllers\Auth\LoginController::class, 'logout']);
When I call this endpoint, I get an error:
Method Illuminate\Auth\RequestGuard::logout does not exist.
How can I get this logout to work without disabling CSRF protection or enabling GET requets to logout?
Solution 1:[1]
I found this discussion in the Laravel Sanctum repository.
Based on that, I changed my route in routes/api.php like this:
Route::post('/logout', [\App\Http\Controllers\Auth\LoginController::class, 'logout'])
->middleware('auth:web');
This tells the logout API call use SessionGuard instead of RequestGuard, and resolves the issue.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Moshe Katz |
