Search code examples
laravellaravel-sanctum

Laravel sanctum how to check token for all api requests?


I have an rest api /api/example need to provide different json information for authorized and unauthorized users. If I use the standard middleware('auth:sanctum') then the user who has the token will get the information, but the user without it will get the 401 Unauthorized. With this approach, it is necessary to create two different routes for each request 1. without protection 2 with protection. It is not comfortable. Is there a way that when I request with a token, I would receive protected information, and without a token, the usual information, accessible to all users?

Route::middleware('auth:sanctum')->post('/example', ExampleController::class );

Solution

  • You can create your own middleware that checks and grabs the bearertoken and set the user if its passed sanctum guard, and would never return 401 response

    e.i.

    php artisan make:middleware GuestOrAuth
    

    then on app/Http/Middleware/GuestOrAuth.php

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Auth;
    
    class GuestOrAuth {
        
        public function handle(Request $request, Closure $next) {
    
            if ( $request->bearerToken() && Auth::guard('sanctum')->user() ) 
                Auth::setUser( Auth::guard('sanctum')->user() );
                
            return $next($request);
        }
    }
    

    then assign that on $routeMiddleware inside app/Http/Kernel.php

    protected $routeMiddleware = [
        .
        .
        .
        'guest.or.auth' => \App\Http\Middleware\GuestOrAuth::class
    ];
    

    then you can use guest.or.auth instead of auth:sanctum

    Route::middleware('guest.or.auth')->get('/logged', function() {
        return auth()->user() ?? ['message' => 'No Valid User!'];
    });