密码凭证
对于 Web 和本机应用程序中受信任的第一方客户端来说,此授权都是出色的用户体验。
步骤
客户端将要求用户提供其授权凭据(通常是用户名和密码)。
然后,客户端将具有以下正文参数的 POST 请求发送到授权服务器:
- grant_type 授权类型,值为 password
- client_id 客户端 ID
- client_secret 客户端密钥
- scope 具有以空格分隔的已请求范围权限列表。
- username 用户名
- password 密码
授权服务器将使用包含以下属性的 JSON 对象进行响应:
- token_type 值为 Bearer
- expires_in 使用表示访问令牌的 TTL (整数)
- access_token 使用授权服务器的私钥签名的 JWT
- refresh_token 可用于在访问令牌过期时刷新访问令牌
设置
无论在何处初始化对象,请初始化授权服务器的新实例并绑定存储接口和授权代码授予:
// Init our repositories $clientRepository = new ClientRepository(); // instance of ClientRepositoryInterface $scopeRepository = new ScopeRepository(); // instance of ScopeRepositoryInterface $accessTokenRepository = new AccessTokenRepository(); // instance of AccessTokenRepositoryInterface $userRepository = new UserRepository(); // instance of UserRepositoryInterface $refreshTokenRepository = new RefreshTokenRepository(); // instance of RefreshTokenRepositoryInterface // Path to public and private keys $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 ); $grant = new \League\OAuth2\Server\Grant\PasswordGrant( $userRepository, $refreshTokenRepository ); $grant->setRefreshTokenTTL(new \DateInterval('P1M')); // refresh tokens will expire after 1 month // Enable the password grant on the server $server->enableGrantType( $grant, new \DateInterval('PT1H') // access tokens will expire after 1 hour );
实现
请注意:此处的这些示例演示了 Slim 框架的用法;Slim不是使用此库的必要条件,您只需要生成与PSR7兼容的HTTP请求和响应的东西。
客户端将请求访问令牌,因此请创建 /access_token 终结点。
$app->post('/access_token', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) { /* @var \League\OAuth2\Server\AuthorizationServer $server */ $server = $app->getContainer()->get(AuthorizationServer::class); try { // Try to respond to the request return $server->respondToAccessTokenRequest($request, $response); } catch (\League\OAuth2\Server\Exception\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 过期后,需要通过接口返回的 refresh_token 值来,刷新 token。