如果曾经了解oauth2.0原理,也装置后laravel passport的状况下。当初从源码中看看相干的逻辑流程,是如何走的。
在这之前咱们先看下laravel如何判断http客户端申请是一般申请,还是json申请,因为passport 默认是api json申请的。
\vendor\laravel\framework\src\Illuminate\Http\Concerns\InteractsWithContentTypes.php 判断http header 的 Accept 是否带有json或+json。
public function expectsJson() { return ($this->ajax() && ! $this->pjax() && $this->acceptsAnyContentType()) || $this->wantsJson(); } public function wantsJson() { $acceptable = $this->getAcceptableContentTypes(); return isset($acceptable[0]) && Str::contains($acceptable[0], ['/json', '+json']); }
晓得申请办法后,咱们看看如何获取oauth access_token。用php artisan route:list 能够查看到 这条记录
POST| oauth/token| passport.token|Laravel\Passport\Http\Controllers\AccessTokenController@issueToken
前期进入代码查看,\vendor\laravel\passport\src\Http\Controllers\AccessTokenController.php,再进入respondToAccessTokenRequest 这个办法,而respondToAccessTokenRequest 这个办法又是在league 这个库中。没错,passport的验证办法是援用league 的oauth2-server。
public function issueToken(ServerRequestInterface $request) { return $this->withErrorHandling(function () use ($request) { return $this->convertResponse( $this->server->respondToAccessTokenRequest($request, new Psr7Response) ); }); }
当初咱们进去看看 vendor\league\oauth2-server\src\AuthorizationServer.php
public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseInterface $response) { foreach ($this->enabledGrantTypes as $grantType) { //print_r($grantType);exit; if (!$grantType->canRespondToAccessTokenRequest($request)) { continue; } $tokenResponse = $grantType->respondToAccessTokenRequest( $request, $this->getResponseType(), $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] ); if ($tokenResponse instanceof ResponseTypeInterface) { return $tokenResponse->generateHttpResponse($response); } } throw OAuthServerException::unsupportedGrantType(); }
这里解读下
- 循环grant模式(受权码模式、简化模式、明码模式、客户端模式)
- 依据用户申请的grant类型进行生成access_toekn操作,如果不是的就continue掉
- respondToAccessTokenRequest是接口,别离有grant不同grant模式去实现,本文例子用password (\vendor\league\oauth2-server\src\Grant\PasswordGrant.php)
- 生成token间接返回,如果有问题就抛异样
咱们再到PasswordGrant这里看看
public function respondToAccessTokenRequest( ServerRequestInterface $request, ResponseTypeInterface $responseType, DateInterval $accessTokenTTL ) { // Validate request $client = $this->validateClient($request); $scopes = $this->validateScopes($this->getRequestParameter('scope', $request, $this->defaultScope)); $user = $this->validateUser($request, $client); // Finalize the requested scopes $finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $user->getIdentifier()); // Issue and persist new access token $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $user->getIdentifier(), $finalizedScopes); $this->getEmitter()->emit(new RequestAccessTokenEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request, $accessToken)); $responseType->setAccessToken($accessToken); // Issue and persist new refresh token if given $refreshToken = $this->issueRefreshToken($accessToken); if ($refreshToken !== null) { $this->getEmitter()->emit(new RequestRefreshTokenEvent(RequestEvent::REFRESH_TOKEN_ISSUED, $request, $refreshToken)); $responseType->setRefreshToken($refreshToken); } return $responseType; }
这里比拟重点就是这3个验证,别离是整体传过来的客户端数据格式验证,之后是oauth scope权限验证,跟着就是依据账号密码查数据库用户验证
$client = $this->validateClient($request); $scopes = $this->validateScopes($this->getRequestParameter('scope', $request, $this->defaultScope)); $user = $this->validateUser($request, $client);
直到这里咱们laravel passport整个oauth2 生成access_token的外围逻辑代码流程曾经实现了。前面咱们看看在中间件中他们是判断token的合法性
在routes.php看到中间件是auth:api
Route::middleware('auth:api')->get('/user', function (Request $request) { echo 'hello world'; });
次要是这个文件vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php authenticate 这个办法,参数grauds就是接管:api这个参数,这个参数会变成config 下auth.php的passport去解密验证,这个逻辑就在\vendor\laravel\framework\src\Illuminate\Auth\AuthManager.php guard()这个办法外面
protected function authenticate($request, array $guards) { if (empty($guards)) { $guards = [null]; } foreach ($guards as $guard) { if ($this->auth->guard($guard)->check()) { return $this->auth->shouldUse($guard); } } $this->unauthenticated($request, $guards); }
这里就从生成到验证整个passport oauth2的过程了。