oauth2-server-php-docs 食谱
2017-11-16 02:50
344 查看
一步一步的演练
以下说明提供详细的演练,以帮助您启动并运行OAuth2服务器。要查看实现此库的现有OAuth2服务器的代码库,请查看OAuth2 Demo。初始化您的项目
为您的项目创建一个目录,并拉入这个库文本mkdir my-oauth2-walkthrough cd my-oauth2-walkthrough git clone https://github.com/bshaffer/oauth2-server-php.git -b master
定义你的模式
现在使用以下模式创建默认数据库:MySQL / SQLite / PostgreSQL / MS SQL Server
sqlCREATE TABLE oauth_clients ( client_id VARCHAR(80) NOT NULL, client_secret VARCHAR(80), redirect_uri VARCHAR(2000), grant_types VARCHAR(80), scope VARCHAR(4000), user_id VARCHAR(80), PRIMARY KEY (client_id) ); CREATE TABLE oauth_access_tokens ( access_token VARCHAR(40) NOT NULL, client_id VARCHAR(80) NOT NULL, user_id VARCHAR(80), expires TIMESTAMP NOT NULL, scope VARCHAR(4000), PRIMARY KEY (access_token) ); CREATE TABLE oauth_authorization_codes ( authorization_code VARCHAR(40) NOT NULL, client_id VARCHAR(80) NOT NULL, user_id VARCHAR(80), redirect_uri VARCHAR(2000), expires TIMESTAMP NOT NULL, scope VARCHAR(4000), id_token VARCHAR(1000), PRIMARY KEY (authorization_code) ); CREATE TABLE oauth_refresh_tokens ( refresh_token VARCHAR(40) NOT NULL, client_id VARCHAR(80) NOT NULL, user_id VARCHAR(80), expires TIMESTAMP NOT NULL, scope VARCHAR(4000), PRIMARY KEY (refresh_token) ); CREATE TABLE oauth_users ( username VARCHAR(80), password VARCHAR(80), first_name VARCHAR(80), last_name VARCHAR(80), email VARCHAR(80), email_verified BOOLEAN, scope VARCHAR(4000) ); CREATE TABLE oauth_scopes ( scope VARCHAR(80) NOT NULL, is_default BOOLEAN, PRIMARY KEY (scope) ); CREATE TABLE oauth_jwt ( client_id VARCHAR(80) NOT NULL, subject VARCHAR(80), public_key VARCHAR(2000) NOT NULL );##引导您的OAuth2服务器我们需要创建和配置我们的OAuth2服务器对象。这将被我们的应用程序中的所有端点使用。命名这个文件
server.php:腓
$dsn = 'mysql:dbname=my_oauth2_db;host=localhost'; $username = 'root'; $password = ''; // error reporting (this is a demo, after all!) ini_set('display_errors',1);error_reporting(E_ALL); // Autoloading (composer is preferred, but for this example let's just do this) require_once('oauth2-server-php/src/OAuth2/Autoloader.php'); OAuth2\Autoloader::register(); // $dsn is the Data Source Name for your database, for exmaple "mysql:dbname=my_oauth2_db;host=localhost" $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password)); // Pass a storage object or array of storage objects to the OAuth2 server class $server = new OAuth2\Server($storage); // Add the "Client Credentials" grant type (it is the simplest of the grant types) $server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage)); // Add the "Authorization Code" grant type (this is where the oauth magic happens) $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage));
注意:一定要定义
$dsn,
$username和
$password变量是数据库的相应值。
创建一个令牌控制器
接下来,我们将创建令牌控制器。这是将OAuth2.0令牌返回给客户端的URI。以下是文件中令牌控制器的示例token.php:腓
// include our OAuth2 Server object require_once __DIR__.'/server.php'; // Handle a request for an OAuth2.0 Access Token and send the response to the client $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();Congratulatons!你已经创建了一个令牌控制器!你想看到它的行动?运行以下SQL来创建一个OAuth客户端:sql
INSERT INTO oauth_clients (client_id, client_secret, redirect_uri) VALUES ("testclient", "testpass", "http://fake/");现在从命令行运行以下命令:文本
curl -u testclient:testpass http://localhost/token.php -d 'grant_type=client_credentials'
注意:http://localhost/token.php假设你
token.php在本地机器上有文件,并且你已经设置了“localhost”虚拟主机来指向它。这可能会因您的应用程序而异。
如果一切正常,你应该收到这样的回应:json
{"access_token":"03807cb390319329bdf6c777d4dfae9c0d3b3c35","expires_in":3600,"token_type":"bearer","scope":null}
创建一个资源控制器
现在您正在创建令牌,您将需要在API中验证它们。以下是文件中资源控制器的示例resource.php:腓
// include our OAuth2 Server object require_once __DIR__.'/server.php'; // Handle a request to a resource and authenticate the access token if (!$server->verifyResourceRequest(OAuth2\Request::createFromGlobals())) { $server->getResponse()->send(); die; } echo json_encode(array('success' => true, 'message' => 'You accessed my APIs!'));现在从命令行运行以下命令:文本
curl http://localhost/resource.php -d 'access_token=YOUR_TOKEN'
注意:使用上一步中的“access_token”中返回的值代替YOUR_TOKEN
如果一切顺利的话,你应该会收到这样的回复:json
{"success":true,"message":"You accessed my APIs!"}
创建一个授权控制器
授权控制器是OAuth2的“杀手级功能”,允许您的用户授权第三方应用程序。与第一个令牌控制器示例中发生的直接发送访问令牌不同,在本示例中,授权控制器用于在用户授权请求后才发布令牌。创建authorize.php:腓
// include our OAuth2 Server object require_once __DIR__.'/server.php'; $request = OAuth2\Request::createFromGlobals(); $response = new OAuth2\Response(); // validate the authorize request if (!$server->validateAuthorizeRequest($request, $response)) { $response->send(); die; } // display an authorization form if (empty($_POST)) { exit(' <form method="post"> <label>Do You Authorize TestClient?</label><br /> <input type="submit" name="authorized" value="yes"> <input type="submit" name="authorized" value="no"> </form>'); } // print the authorization code if the user has authorized your client $is_authorized = ($_POST['authorized'] === 'yes'); $server->handleAuthorizeRequest($request, $response, $is_authorized); if ($is_authorized) { // this is only here so that you get to see your code in the cURL request. Otherwise, we'd redirect back to the client $code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=')+5, 40); exit("SUCCESS! Authorization Code: $code"); } $response->send();现在将以下URL粘贴到您的浏览器中文本
http://localhost/authorize.php?response_type=code&client_id=testclient&state=xyz系统会提示您使用授权表单,并在点击“是”时收到授权码授权码现在可以用来从您以前创建的
token.php端点接收访问令牌。只需使用返回的授权码调用此端点:文本
curl -u testclient:testpass http://localhost/token.php -d 'grant_type=authorization_code&code=YOUR_CODE'和以前一样,您将收到一个访问令牌:json
{"access_token":"6f05ad622a3d32a5a81aee5d73a5826adb8cbf63","expires_in":3600,"token_type":"bearer","scope":null}
注意:请务必迅速执行此操作,因为授权码会在30秒内过期!
将本地用户与访问令牌关联起来
一旦你对一个用户进行了身份验证并发布了一个访问令牌(比如上面的Authorize Controller示例),那么当你使用访问令牌时,你可能会想知道哪个用户是访问令牌的。请查看 用户标识文档以获取有关如何执行此操作的信息。使用外部客户端测试您的授权控制器
如果您想使用“真实”客户端来测试授权控制器,请查看 Google OAuth2 Playground示例Google Playground
使用Google OAuth 2.0 Playground测试您的服务器
一旦你在野外的互联网上建立你的服务器,你会想检查它与独立的客户端。一种方法是使用Google OAuth 2.0 Playground。假设你已经设置了一个授权控制器,你可以按如下方式进行测试:使用上面的链接导航到游乐场。点击右上角的设置按钮。选择“服务器端”作为“OAuth流程”,选择“自定义”作为“OAuth端点”。在授权端点中,输入授权控制器的URL(例如https://domain.com/authorize.php)。在令牌端点中,输入令牌控制器的URL(例如https://domain.com/token.php)。为访问令牌位置选择“授权标头w /承载前缀”。输入客户端ID和密码(如果使用以前的文档示例,则使用testclient和testpass)。在左侧的文本框中输入“basic”,然后单击“授权API”。你应该被带到你的网站,你可以授权请求,之后你应该返回到游乐场。点击“兑换令牌授权码”即可接收令牌(您需要在30秒内完成)。在右边的回应应该显示访问令牌。输入资源页面的URL(例如https://domain.com/resource.php)。添加你想要的任何可选参数,然后点击“发送请求”。如果您以前使用过相同的代码,则应该看到相同的响应:json{"success":true,"message":"You accessed my APIs!"}[/code]
Drupal的
对于drupal集成,请参阅bojanz的OAuth2服务器模块。Zend框架
为了这个库与Zend框架2整合,你可以使用这些模块之一:* OAuth2Provider由弗兰茨·德利恩* ZF2-的oauth2提供商由格伦·施密特Laravel
在Laravel 4中查看这个Laravel演示应用程序来实现这个库。一步一步的演练
创建你的Laravel项目(例如composer create-project laravel/laravel --prefer-dist)使用Composer:
composer require bshaffer/oauth2-server-php和安装OAuth2服务器和HTTPFoundation网桥依赖关系
composer require bshaffer/oauth2-server-httpfoundation-bridge设置您的数据库并运行提供的迁移(请参阅https://github.com/julien-c/laravel-oauth2-server/commit/b290d4f699b9758696444e2d62dd82f0eeedcb7d):
php artisan db:migrate使用提供的脚本对数据库进行种子处理:https://github.com/julien-c/laravel-oauth2-server/commit/8895c54cbf8ea8ba78aafab53a5a0409ce2f1ba2
php artisan db:seed设置您的OAuth2服务器。为了能够访问Laravel应用程序中任何位置的单个实例,可以将其作为单例添加:腓
App::singleton('oauth2', function() { $storage = new OAuth2\Storage\Pdo(App::make('db')->getPdo()); $server = new OAuth2\Server($storage); $server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage)); $server->addGrantType(new OAuth2\GrantType\UserCredentials($storage)); return $server; });实施您希望实施的实际OAuth2控制器。例如令牌控制器和资源控制器:请参阅
app/routes.php你甚至可以单元测试你的整合!下面是一个使用Guzzle的例子:https://github.com/julien-c/laravel-oauth2-server/blob/master/app/tests/OAuthTest.php
教义
创建客户端和访问令牌存储
要把学说融入到你的项目中,首先要建立你的模型。我们先从客户端和访问令牌模型开始:yamlOAuthClient: tableName: oauth_client columns: client_identifier: type: string(50) notnull: true client_secret: type: char(20) notnull: false redirect_uri: type: string(255) notnull: true default: "" OAuthAccessToken: tableName: oauth_access_token columns: token: type: char(40) notnull: true unique: true client_identifier: type: string(50) notnull: true user_identifier: type: string(100) notnull: true expires: type: timestamp notnull: true scope: type: string(50) notnull: false relations: Client: local: client_identifier foreign: client_identifier class: OAuthClient foreignAlias: AccessTokens onDelete: CASCADE onUpdate: CASCADE一旦你从这个模式中生成模型,你将有一个
OAuthClient和
OAuthCleintTable类文件,以及一个
OAuthAccessToken和
OAuthAccessTokenTable对象。
OAuth2\Storage\ClientCredentialsInterface在
OAuthClientTable课堂上实施:腓
class OAuthClientTable extends Doctrine_Table implements OAuth2\Storage\ClientCredentialsInterface { public function getClientDetails($client_id) { $client = $this->createQuery() ->where('client_identifier = ?', $client_id) ->fetchOne(array(), Doctrine::HYDRATE_ARRAY); return $client; } public function checkClientCredentials($client_id, $client_secret = NULL) { $client = $this->getClientDetails($client_id); if ($client) { return $client['client_secret'] === sha1($client_secret); } return false; } public function checkRestrictedGrantType($client_id, $grant_type) { // we do not support different grant types per client in this example return true; } }现在
OAuth2\Storage\AccessTokenInterface在
OAuthAccessTokenTable课堂上实施:腓
class OAuthAccessTokenTable extends Doctrine_Table implements OAuth2\Storage\AccessTokenInterface { public function getAccessToken($oauth_token) { $token = $this->createQuery() ->where('token = ?', $oauth_token) ->fetchOne(array(), Doctrine_Core::HYDRATE_ARRAY); if ($token) { return array( 'token' => $token['token'], 'client_id' => $token['client_identifier'], 'expires' => strtotime($token['expires']), 'scope' => $token['scope'], 'user_id' => $token['user_identifier'], ); } } public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null) { $token = new OAuthAccessToken(); $token->fromArray(array( 'token' => $oauth_token, 'client_identifier' => $client_id, 'user_identifier' => $user_id, 'expires' => date('Y-m-d H:i:s', $expires), 'scope' => $scope, )); $token->save(); } }做得好!现在,当你创建你的
OAuth\Server对象的时候,把这些表传递给:腓
$clientStore = Doctrine::getTable('OAuthClient'); $tokenStore = Doctrine::getTable('OAuthAccessToken'); // Pass the doctrine storage objects to the OAuth2 server class $server = new OAuth2\Server(array('client_credentials' => $clientStore, 'access_token' => $tokenStore));你做到了!你已经把你的服务器与主义联系起来了!你可以去镇使用它,但因为你只通过它
client_credentials与
access_token存储对象,你只能用
client_credentials批类型:腓
// will only be able to handle token requests when "grant_type=client_credentials". $server->addGrantType(new OAuth2\GrantType\ClientCredentials($clientStore)); // handle the request $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();添加授权码和刷新令牌存储----------------所以让我们的应用程序更加精彩一点。将以下内容添加到您的模式并生成类文件:yaml
OAuthAuthorizationCode: tableName: oauth_authorization_code columns: code: type: char(40) notnull: true unique: true client_identifier: type: string(50) notnull: true expires: type: timestamp notnull: true user_identifier: type: string(100) notnull: true redirect_uri: type: string(200) notnull: true scope: type: string(50) notnull: false relations: Client: local: client_identifier foreign: client_identifier class: OAuthClient foreignAlias: AuthorizationCodes onDelete: CASCADE onUpdate: CASCADE OAuthRefreshToken: tableName: oauth_refresh_token columns: refresh_token: type: char(40) notnull: true unique: true client_identifier: type: string(50) notnull: true user_identifier: type: string(100) notnull: true expires: type: timestamp notnull: true scope: type: string(50) notnull: false relations: Client: local: client_identifier foreign: client_identifier class: OAuthClient foreignAlias: RefreshTokens onDelete: CASCADE onUpdate: CASCADE现在,我们可以实现两个接口,
OAuth2\Storage\AuthorizationCodeInterface和
OAuth2\Storage\RefreshTokenInterface。这将允许我们使用他们的对应授权类型。
OAuth2\Storage\AuthorizationCodeInterface在
OAuthAuthorizationCodeTable课堂上实施:腓
class OAuthAuthorizationCodeTable extends Doctrine_Table implements OAuth2\Storage\AuthorizationCodeInterface { public function getAuthorizationCode($code) { $auth_code = $this->createQuery() ->where('code = ?', $code) ->fetchOne(array(), Doctrine_Core::HYDRATE_ARRAY); if ($auth_code) { return array( 'code' => $auth_code['code'], 'client_id' => $auth_code['client_identifier'], 'user_id' => $auth_code['web_service_username'], 'redirect_uri' => $auth_code['redirect_uri'], 'expires' => strtotime($auth_code['expires']), 'scope' => $auth_code['scope'], ); } return null; } public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null) { $auth_code = new OAuthAuthorizationCode(); $auth_code->fromArray(array( 'code' => $code, 'client_identifier' => $client_id, 'web_service_username' => $user_id, 'redirect_uri' => $redirect_uri, 'expires' => date('Y-m-d H:i:s', $expires), 'scope' => $scope, )); $auth_code->save(); } public function expireAuthorizationCode($code) { return $this->createQuery() ->delete() ->where('code = ?', $code) ->execute(); } }
OAuth2\Storage\RefreshTokenInterface在
OAuthRefreshTokenTable课堂上实施:腓
class OAuthRefreshTokenTable extends Doctrine_Table implements OAuth2\Storage\RefreshTokenInterface { public function getRefreshToken($refresh_token) { $refresh_token = $this->createQuery() ->where('refresh_token = ?', $refresh_token) ->fetchOne(array(), Doctrine_Core::HYDRATE_ARRAY); if ($auth_code) { return array( 'refresh_token' => $refresh_token['refresh_token'], 'client_id' => $refresh_token['client_identifier'], 'user_id' => $refresh_token['user_identifier'], 'expires' => strtotime($refresh_token['expires']), 'scope' => $refresh_token['scope'], ); } } public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null) { $refresh_token = new OAuthRefreshToken(); $refresh_token->fromArray(array( 'code' => $code, 'client_identifier' => $client_id, 'user_identifier' => $user_id, 'expires' => date('Y-m-d H:i:s', $expires), 'scope' => $scope, )); $refresh_token->save(); } public function unsetRefreshToken($refresh_token) { return $this->createQuery() ->delete() ->where('refresh_token = ?', $refresh_token) ->execute(); } }现在我们可以在我们的服务器上添加两个授权类型:腓
$clientStore = Doctrine::getTable('OAuthClient'); $tokenStore = Doctrine::getTable('OAuthAccessToken'); $codeStore = Doctrine::getTable('OAuthAuthorizationCode'); $refreshStore = Doctrine::getTable('OAuthRefreshToken'); // Pass the doctrine storage objects to the OAuth2 server class $server = new OAuth2\Server(array( 'client_credentials' => $clientStore, 'access_token' => $tokenStore, 'authorization_code' => $codeStore, 'refresh_token' => $refreshStore, )); $server->addGrantType(new OAuth2\GrantType\ClientCredentials($clientStorage)); $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($codeStorage)); $server->addGrantType(new OAuth2\GrantType\RefreshToken($refreshStorage)); // handle the request $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();你做到了!好吧,几乎所有的。唯一剩下的就是添加你的用户!那么,请参阅symfony文档以了解如何与之集成
sfGuardUser。
相关文章推荐
- oauth2-server-php-docs 概念
- oauth2-server-php-docs 授权类型
- oauth2-server-php-docs 存储
- oauth2-server-php-docs 存储 学说2
- oauth2-server-php-docs 集成3
- oauth2-server-php for windows 的那些坑 (研究中...)
- php创建oauth2 server
- OAuth2 Server php
- OAuth2-Server-php
- oauth2-server-php-docs 授权控制器
- oauth2 server php
- php中_SERVER参数说明
- $_SERVER PHP URL
- 详解$_SERVER 函数中QUERY_STRING、REQUEST_URI、SCRIPT_NAME和'PHP_SELF
- PHP socket,server,cient:模拟 post
- [转]ubuntu11 安装redis server 和phpredis
- PHP中$_SERVER的具体參数与说明
- PHP $_SERVER['HTTP_HOST']与$_SERVER["SERVER_NAME"]的区别
- ubuntu1604-server上安装virtualbox+phpvirtualbox