drahak / oauth2
Nette OAuth2 提供程序包
此包的规范存储库似乎已消失,因此已冻结此包。
Requires
- php: >= 5.3.0
- nette/nette: @dev
Requires (Dev)
- janmarek/mockista: dev-master
- nette/tester: dev-master
This package is not auto-updated.
Last update: 2024-01-20 11:33:05 UTC
README
此存储库正在开发中,非常不稳定。
要求
Drahak/OAuth2 需要 PHP 版本 5.3.0 或更高版本。唯一的生成依赖是 Nette 框架 2.0.x。
安装和设置
最简单的方法是使用 Composer
$ composer require drahak/oauth2:@dev
然后在创建容器之前将以下代码添加到您的应用程序引导文件中
Drahak\OAuth2\DI\Extension::install($configurator);
或将其注册到 config.neon 中
extensions: restful: Drahak\Restful\DI\RestfulExtension
Neon 配置
oauth2: accessTokenLifetime: 3600 # 1 hour refreshTokenLifetime: 36000 # 10 hours authorizationCodeLifetime: 360 # 6 minutes storage: 'ndb' # allowed values: 'ndb', 'dibi' accessTokenStorage: 'Drahak\OAuth2\Storage\NDB\AccessTokenStorage' authorizationCodeStorage: 'Drahak\OAuth2\Storage\NDB\AuthorizationCodeStorage' clientStorage: 'Drahak\OAuth2\Storage\NDB\ClientStorage' refreshTokenStorage: 'Drahak\OAuth2\Storage\NDB\RefreshTokenStorage'
accessTokenLifetime
- 访问令牌生命周期(秒)refreshTokenLifetime
- 刷新令牌生命周期(秒)authorizationCodeLifetime
- 授权码生命周期(秒)storage
- 存储将在默认 NDB 和 dibi 存储之间切换。您可以为每个存储部分使用自己的存储。
OAuth2
抽象协议流程
+--------+ +---------------+
| |------ Authorization Request ->| Resource |
| | | Owner |
| |<------ Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |------- Authorization Grant -->| Authorization |
| Client | | Server |
| |<--------- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |---------- Access Token ------>| Resource |
| | | Server |
| |<------- Protected Resource ---| |
+--------+ +---------------+
OAuth 角色
客户端 - 第三方应用程序
此应用程序想要从资源服务器获取用户数据,因此它需要获取一个访问令牌。
资源服务器 - API
客户端想要的数据。API 服务器使用访问令牌来访问用户信息。
资源所有者
允许访问其账户的一部分。
另请参阅 OAuth 2 简化 和 原始规范
OAuth 演示者
演示者(IOAuthPresenter
)提供访问权限。在基本实现中,它有 2 个主要方法,issueAccessToken
和 issueAuthorizationCode
。简单的 OAuth(资源所有者)演示者可能看起来像这样
namespace MyApp\OAuth; use Drahak\OAuth2\Grant\IGrant; use Drahak\OAuth2\Application; use Drahak\OAuth2\OAuthException; class AuthorizationPresenter extends Application\OAuthPresenter { /** * Authorization * @param string $response_type * @param string $redirect_uri * @param string|null $scope */ public function actionAuthorize($response_type, $redirect_uri, $scope = NULL) { if (!$this->user->isLoggedIn()) { $this->redirect('AnyUser:login', array('backlink' => $this->storeRequest())); } if ($response_type == 'code') { $this->issueAuthorizationCode($response_type, $redirect_uri, $scope); } else if ($response_type == 'token') { $this->issueAccessToken(IGrant::IMPLICIT, $redirect_uri); } } /** * Access token provider */ public function actionToken() { try { $this->issueAccessToken(); } catch (OAuthException $e) { $this->oauthError($e); } } }
方法 issueAccessToken
从 grant_type
参数中确定正确的授权类型。在出现错误时,抛出一些 OAuthException
,这可以在默认实现中的 oauthError
方法中处理。
操作 authorize
较为复杂。这用于生成授权码(见下文 - 授权码),但对于隐式授权类型,此处需要生成访问令牌。如果用户未登录,请将用户重定向到某个登录页面,然后使用回链恢复授权请求。
授权类型
由 grant_type
参数确定。支持 OAuth2 规范中定义的基本授权类型:授权码、隐式、密码、客户端凭据和刷新令牌。
- 授权码
此授权类型非常适合第三方应用程序,可以安全地存储客户端密钥代码。
要生成访问令牌,首先需要获取授权码。您可以通过调用 issueAuthorizationCode
从 IOAuthPresenter
获取它。
请求授权码
GET //oauth.presenter.url/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=email
- [必需] response_type - 您希望生成授权
code
- [必需] client_id - 请求访问令牌的客户端 ID(例如应用)
- [必需] redirect_uri - 成功或错误时重定向的 URL 地址
- [可选] scope - 指定访问请求的范围
授权码响应
在任何情况下(错误或成功),资源所有者都会使用 redirect_uri
将客户端重定向回去,其中包含作为查询参数的授权码
//redirect_uri/?code=AnlSCIWYbchsCc5sdc5ac4caca8a2
或者
//redirect_uri/?error=unauthorized_client&error_description=Client+is+not+found
由于您已经有了授权码,您可以发出访问令牌请求(数据作为 application/x-www-form-urlencoded
提供)
请求访问令牌
POST //oauth.presenter.url/token
grant_type=authorization_code
&code=AUTHORIZATION_CODE
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
- [必需] grant_type - 此参数告诉 OAuth 使用授权码
- [必需] code - 从资源所有者那里获得的授权码
- [必需] client_id - 请求访问令牌的客户端 ID(例如应用)
- [必需] client_secret - 请求访问令牌的客户端(例如应用)的密钥
访问令牌响应
{
"access_token": "AnlSCIWYbchsCc5sdc5ac4caca8a2",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "DS6SA512ADCVa51adc54VDS51VD5"
}
在出现错误的情况下,提供 JSON 响应
{
"error": "invalid_request",
"error_description": "Invalid authorization code"
}
- 隐式
用于基于浏览器(Web)或移动应用程序,在这些应用程序中,您无法安全地存储客户端密钥,因此您不能使用它来获取访问令牌。
请求访问令牌
GET //oauth.presenter.url/authorization?response_type=token&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=email
- [必需] response_type - 由于您从资源所有者请求访问令牌,您必须告诉您需要一个访问令牌(而不是授权码)
- [必需] client_id - 请求访问令牌的客户端 ID(例如应用)
- [必需] redirect_uri - 成功或错误时重定向的 URL
- [可选] scope - 指定访问请求的范围
访问令牌响应
重定向到 redirect_uri
//redirect_uri/#access_token=AnlSCIWYbchsCc5sdc5ac4caca8a2&expires_in=3600&token_type=bearer
在出现错误的情况下,重定向到
//redirect_uri/#error=unauthorized_client&error_description=Client+is+not+found
- 密码
用于受信任(通常是第一方)的应用程序,您完全信任客户端,因为您从真实用户凭据(用户名、密码)生成访问令牌。
请求访问令牌
POST //oauth.presenter.url/token
grant_type=password
&username=USERNAME
&password=PASSWORD
&client_id=CLIENT_ID
- [必需] grant_type - 密码授权类型使用标识符(出人意料地)
password
- [必需] client_id - 请求访问令牌的客户端 ID(例如应用)
- [必需] username - 真实用户的用户名
- [可选] password - 真实用户的密码
访问令牌响应
{
"access_token": "AnlSCIWYbchsCc5sdc5ac4caca8a2",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "DS6SA512ADCVa51adc54VDS51VD5"
}
在出现错误的情况下
{
"error": "invalid_request",
"error_description": "Invalid authorization code"
}
- 客户端凭据
如果应用需要在任何特定用户上下文之外获取其账户的访问令牌,这可能是最佳方法。
请求访问令牌
POST //oauth.presenter.url/token
grant_type=client_credentials
&client_id=CLIENT_ID
&client_SECRET=CLIENT_SECRET
- [必需] grant_type - 密码授权类型使用标识符(出人意料地)
password
- [必需] client_id - 请求访问令牌的客户端 ID(例如应用)
- [必需] client_secret - 请求访问令牌的客户端(例如应用)的密钥
访问令牌响应
{
"access_token": "AnlSCIWYbchsCc5sdc5ac4caca8a2",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "DS6SA512ADCVa51adc54VDS51VD5"
}
在出现错误的情况下
{
"error": "invalid_request",
"error_description": "Invalid authorization code"
}
- 刷新令牌
用于在不进行身份验证过程的情况下恢复(实际上重新生成)访问令牌。几乎每种授权类型都提供刷新令牌(除隐式授权外)。
请求刷新令牌
POST //oauth.presenter.url/token
grant_type=refresh_token
&refresh_token=DS6SA512ADCVa51adc54VDS51VD5
&client_id=CLIENT_ID
- [必填] grant_type - 刷新令牌标识符
- [必填] refresh_token - 刷新令牌本身,您几乎可以从任何访问令牌中获取
- [必需] client_id - 请求访问令牌的客户端 ID(例如应用)
访问令牌响应
{
"access_token": "AnlSCIWYbchsCc5sdc5ac4caca8a2",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "DS6SA512ADCVa51adc54VDS51VD5"
}
在出现错误的情况下
{
"error": "invalid_request",
"error_description": "Invalid refresh token"
}