laravel / passport for middleware('auth:api')向数据库发送多个请求

时间:2018-03-25 17:22:34

标签: laravel oauth jwt laravel-passport

我使用https://laravel.com/docs/5.4/passport来验证用户,如果护照是基于JWT的,为什么要向数据库发送多个请求以检查中间件('auth:api')?

1 个答案:

答案 0 :(得分:0)

修改 我认为误解是使用JWT意味着无状态身份验证。您可以将客户端令牌状态存储在服务器上,并将JWT与客户端存储在一起,并通过数据库调用(Laravel Passport)进行验证,但是这有其优点/缺点。


auth:api中间件/防护是有状态的(不是无状态的)。您需要使用其他软件包或创建使用无状态身份验证的自己的中间件/防护。

最初,这也使我感到困惑,因为$user->createToken()->accessToken;返回JSON Web令牌(JWT),并且我假设无状态身份验证(错误的假设)。

要了解这种情况在框架中的发生方式:

auth:api中间件使用“ api”防护(默认在config/auth.php中定义)。驱动程序是Laravel\Passport\PassportServiceProvider.php,它注册了Laravel\Passport\Guards\TokenGuard.php

是TokenGuard检查Authorization标头和Bearer令牌。如果找到了Bearer令牌,则防护程序尝试通过TokenGuard.php中的authenticateViaBearerToken函数对用户进行身份验证。在此过程中,将进行各种数据库调用来检索用户,创建令牌对象并确定令牌是否已被吊销。

这是Laravel v5.6中的authenticateViaBearerToken(为清楚起见删除了注释):

/**
 * 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);
    }
}