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