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

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

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

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


auth:api middleware/guard 是有状态的(不是无状态的)。您需要使用其他包或创建自己的 middleware/guard 使用无状态身份验证。

最初,这也让我感到困惑,因为 $user->createToken()->accessToken; returns 一个 JSON Web 令牌 (JWT) 而我假设是无状态身份验证(错误的假设)。

要了解框架中这是如何发生的:

auth:api 中间件使用 'api' 守卫(默认情况下在 config/auth.php 中定义)。 driver 是 Laravel\Passport\PassportServiceProvider.php,它注册了 Laravel\Passport\Guards\TokenGuard.php

检查授权 header 和 Bearer 令牌的是 TokenGuard。如果找到 Bearer 令牌,则守卫会尝试通过 TokenGuard.php 中的 authenticateViaBearerToken 函数对用户进行身份验证。这样做时,会调用各种数据库来检索用户、创建令牌 object 并确定令牌是否已被撤销。

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

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