当前位置: 首页 > 后端技术 > PHP

laravelpassport之oauth2机制(二)——源码解读

时间:2023-03-30 01:31:05 PHP

如果你了解了oauth2.0的原理,也可以安装laravelpassport。现在从源码来看相关的逻辑流程,是怎么回事。在此之前,先看看laravel是如何判断http客户端请求是普通请求还是json请求的,因为passport默认是apijson请求。\vendor\laravel\framework\src\Illuminate\Http\Concerns\InteractsWithContentTypes.php判断http头的Accept是包含json还是+json。publicfunctionexpectsJson(){return($this->ajax()&&!$this->pjax()&&$this->acceptsAnyContentType())||$this->wantsJson();}publicfunctionwantsJson(){$acceptable=$this->getAcceptableContentTypes();返回isset($acceptable[0])&&Str::contains($acceptable[0],['/json','+json']);}知道了request方法,我们再看看如何获??取oauthaccess_token。使用phpartisanroute:list查看这条记录POST|oauth/令牌|passport.token|Laravel\Passport\Http\Controllers\AccessTokenController@issueToken后面进入代码查看,\vendor\laravel\passport\src\Http\Controllers\AccessTokenController.php,然后进入respondToAccessTokenRequest方法,respondToAccessTokenRequest方法为在联盟图书馆。没错,passport验证方式就是参考联盟的oauth2-server。publicfunctionissueToken(ServerRequestInterface$request){return$this->withErrorHandling(function()use($request){return$this->convertResponse($this->server->respondToAccessTokenRequest($request,newPsr7Response));});}现在我们去看看vendor\league\oauth2-server\src\AuthorizationServer.phppublicfunctionrespondToAccessTokenRequest(ServerRequestInterface$request,ResponseInterface$response){foreach($this->enabledGrantTypesas$grantType){//print_r($grantType);出口;如果(!$grantType->canRespondToAccessTokenRequest($request)){继续;$tokenResponse=$grantType->respondToAccessTokenRequest($request,$this->getResponseType(),$this->grantTypeAccessTokenTTL[$grantType->getIdentifier()]);如果($tokenResponseinstanceofResponseTypeInterface){return$tokenResponse->generateHttpResponse($response);}}}抛出OAuthServerException::unsupportedGrantType();}这里根据用户请求解释循环的授权形式(授权码模式、简化模式、密码模式、客户端模式)授权类型用于生成access_toekn操作。如果没有,继续respondToAccessTokenRequest是一个接口,在不同的授权形式中实现。本例使用password(\vendor\league\oauth2-server\src\Grant\PasswordGrant.php)生成token直接返回,如果有问题会抛出异常。我们去PasswordGrant看看publicfunctionrespondToAccessTokenRequest(ServerRequestInterface$request,ResponseTypeInterface$responseType,DateInterval$accessTokenTTL){//Validaterequest$client=$this->validateClient($request);$scopes=$this->validateScopes($this->getRequestParameter('scope',$request,$this->defaultScope));$user=$this->validateUser($request,$client);//完成请求的作用域$finalizedScopes=$this->scopeRepository->finalizeScopes($scopes,$this->getIdentifier(),$client,$user->getIdentifier());//发布并保留新的访问令牌$accessToken=$this->issueAccessToken($accessTokenTTL,$client,$user->getIdentifier(),$finalizedScopes);$this->getEmitter()->emit(newRequestAccessTokenEvent(RequestEvent::ACCESS_TOKEN_ISSUED,$request,$accessToken));$responseType->setAccessToken($accessToken);//如果给定$refreshToken=$this->issueRefreshToken($accessToken);//发出并保留新的刷新令牌如果($refreshToken!==null){$this->getEmitter()->emit(newRequestRefreshTokenEvent(RequestEvent::REFRESH_TOKEN_ISSUED,$request,$refreshToken));$responseType->setRefreshToken($refreshToken);}返回$responseType;}这里重点是这三个验证,分别是客户端整体数据格式的验证,其次是oauthScope权限验证,其次是根据账号密码检查数据库用户验证$client=$this->validateClient($请求);$范围s=$this->validateScopes($this->getRequestParameter('scope',$request,$this->defaultScope));$user=$this->validateUser($request,$client);到这里我们laravelpassport整个oauth2生成access_token的核心逻辑代码流程已经完成后面看中间件他们判断token的合法性。在routes.php中,我们看到中间件是auth:apiRoute::middleware('auth:api')->get('/user',function(Request$request){echo'helloworld';});主要是这个文件vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.phpauthenticate这个方法,参数grauds是接收:api这个参数,这个参数会变createthepassportofauth.phpunderconfig去解密并验证。这个逻辑在\vendor\laravel\framework\src\Illuminate\Auth\AuthManager.phpguard()protectedfunctionauthenticate($request,array$guards){if(empty($guards)){$guards=方法中[无效的];}foreach($guardsas$guard){if($this->auth->guard($guard)->check()){返回$this->auth->shouldUse($guard);$this->unauthenticated($request,$guards);}下面是passportoauth2从生成到验证的全过程。参考https://www.cntofu.com/book/107/Laravel%20Passport%E2%80%94%E2%80%94OAuth2%20API%20%E8%AE%A4%E8%AF%81%E7%B3%BB%E7%BB%9F%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90%EF%BC%88%E4%B8%8B%EF%BC%89.MD