隐性授权
不再推荐使用隐性授权。该授权方式仅出于遗留目的而记录在此处。行业最佳实践建议使用授权码,对于本地和基于浏览器的应用程序不需要客户端密钥。
隐性授权类似于授权码授权,但有两个明显的区别。
它旨在用于无法保留客户端机密的基于用户代理的客户端(例如单页 Web 应用程序),因为所有应用程序代码和存储都可以轻松访问。
其次,授权服务器返回的不是授权服务器返回交换访问令牌的授权代码,而是访问令牌。
使用
- response_type 响应类型,值为 token
- client_id 客户端标识
- redirect_uri 使用客户端重定向 URI。此参数是可选的,但如果未发送,用户将被重定向到预注册的重定向 URI。
- scope 以空格分隔的范围列表
- state 使用 CSRF 令牌。此参数是可选的,但强烈建议使用。您应该将 CSRF 令牌的值存储在用户的会话中,以便在用户返回时进行验证。
所有这些参数都将由授权服务器验证。
然后,将要求用户登录到授权服务器并批准客户端。
如果用户批准客户端,则会在查询字符串中使用以下参数将其重定向回授权服务器:
token_type 值为 Bearer expires_in 使用表示访问令牌的 TTL (整数) access_token 使用授权服务器的私钥签名的 JWT state 在原始请求中发送状态参数。应将此值与存储在用户会话中的值进行比较,以确保获取的授权代码响应此客户端而不是其他客户端应用程序发出的请求。
注意:此授权不会返回刷新令牌。
设置
无论在何处初始化对象,请初始化授权服务器的新实例并绑定存储接口和授权码:
// Init our repositories $clientRepository = new ClientRepository(); // instance of ClientRepositoryInterface $scopeRepository = new ScopeRepository(); // instance of ScopeRepositoryInterface $accessTokenRepository = new AccessTokenRepository(); // instance of AccessTokenRepositoryInterface $authCodeRepository = new AuthCodeRepository(); // instance of AuthCodeRepositoryInterface $privateKey = 'file://path/to/private.key'; //$privateKey = new CryptKey('file://path/to/private.key', 'passphrase'); // if private key has a pass phrase $encryptionKey = 'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen'; // generate using base64_encode(random_bytes(32)) // Setup the authorization server $server = new \League\OAuth2\Server\AuthorizationServer( $clientRepository, $accessTokenRepository, $scopeRepository, $privateKey, $encryptionKey ); // Enable the implicit grant on the server $server->enableGrantType( new ImplicitGrant(new \DateInterval('PT1H')), new \DateInterval('PT1H') // access tokens will expire after 1 hour );
实现
请注意:此处的这些示例演示了 Slim 框架的用法;Slim不是使用此库的必要条件,您只需要生成与PSR7兼容的HTTP请求和响应的东西。
客户端会将用户重定向到授权终结点。
$app->get('/authorize', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) { /* @var \League\OAuth2\Server\AuthorizationServer $server */ $server = $app->getContainer()->get(AuthorizationServer::class); try { // Validate the HTTP request and return an AuthorizationRequest object. $authRequest = $server->validateAuthorizationRequest($request); // The auth request object can be serialized and saved into a user's session. // You will probably want to redirect the user at this point to a login endpoint. // Once the user has logged in set the user on the AuthorizationRequest $authRequest->setUser(new UserEntity()); // an instance of UserEntityInterface // At this point you should redirect the user to an authorization page. // This form will ask the user to approve the client and the scopes requested. // Once the user has approved or denied the client update the status // (true = approved, false = denied) $authRequest->setAuthorizationApproved(true); // Return the HTTP redirect response return $server->completeAuthorizationRequest($authRequest, $response); } catch (OAuthServerException $exception) { // All instances of OAuthServerException can be formatted into a HTTP response return $exception->generateHttpResponse($response); } catch (\Exception $exception) { // Unknown exception $body = new Stream('php://temp', 'r+'); $body->write($exception->getMessage()); return $response->withStatus(500)->withBody($body); } });
过期
token 过期后,需要重新发起上述操作。