Search code examples
laraveloauthjwtlaravel-passport

laravel/passport for middleware('auth:api') Send multi request to the database


I use https://laravel.com/docs/5.4/passport to Authentication the user,If the passport is based on JWT,Why send multi requests to the database for checking middleware('auth:api')?


Solution

  • Edit I think the misconception is that using a JWT implies stateless authentication. You can store client token state on the server and store the JWT with the client and verify this with database calls (Laravel Passport), but there are pros/cons to this.


    The auth:api middleware/guard is stateful (not stateless). You'll need to use another package or create your own middleware/guard that uses stateless authentication.

    Initially, this confused me up too, since $user->createToken()->accessToken; returns a JSON Web Token (JWT) and I was assuming stateless authentication (wrong assumption).

    To understand how this happens in the framework:

    The auth:api middleware uses the 'api' guard (Defined in config/auth.php by default). The driver for this is Laravel\Passport\PassportServiceProvider.php which registers the Laravel\Passport\Guards\TokenGuard.php

    It is the TokenGuard that checks for the Authorization header and Bearer token. If the Bearer token is found, then the guard attempts to authenticate the user via the authenticateViaBearerToken function within TokenGuard.php. In doing so, there are various database calls that are made to retrieve the user, create a token object, and determine if the token has been revoked.

    Here is the authenticateViaBearerToken as of Laravel v5.6 (removed comments for clarity):

    /**
     * Authenticate the incoming request via the Bearer token.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return mixed
     */
    protected function authenticateViaBearerToken($request)
    {
        $psr = (new DiactorosFactory)->createRequest($request);
        try {
            $psr = $this->server->validateAuthenticatedRequest($psr);
    
            $user = $this->provider->retrieveById(
                $psr->getAttribute('oauth_user_id')
            );
            if (! $user) {
                return;
            }
    
            $token = $this->tokens->find(
                $psr->getAttribute('oauth_access_token_id')
            );
            $clientId = $psr->getAttribute('oauth_client_id');
    
            if ($this->clients->revoked($clientId)) {
                return;
            }
            return $token ? $user->withAccessToken($token) : null;
        } catch (OAuthServerException $e) {
            $request->headers->set( 'Authorization', '', true );
            Container::getInstance()->make(
                ExceptionHandler::class
            )->report($e);
        }
    }