分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

oauth2-server-php-docs 食谱

发布时间:2023-09-06 01:25责任编辑:沈小雨关键词:暂无标签

一步一步的演练

以下说明提供详细的演练,以帮助您启动并运行OAuth2服务器。要查看实现此库的现有OAuth2服务器的代码库,请查看OAuth2 Demo。

初始化您的项目

为您的项目创建一个目录,并拉入这个库

文本
mkdir my-oauth2-walkthroughcd my-oauth2-walkthroughgit clone https://github.com/bshaffer/oauth2-server-php.git -b master

定义你的模式

现在使用以下模式创建默认数据库:

MySQL / SQLite / PostgreSQL / MS SQL Server

sql
CREATE 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 objectrequire_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 objectrequire_once __DIR__.‘/server.php‘;// Handle a request to a resource and authenticate the access tokenif (!$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 objectrequire_once __DIR__.‘/server.php‘;$request = OAuth2\Request::createFromGlobals();$response = new OAuth2\Response();// validate the authorize requestif (!$server->validateAuthorizeRequest($request, $response)) { ???$response->send(); ???die;}// display an authorization formif (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。

假设你已经设置了一个授权控制器,你可以按如下方式进行测试:

  1. 使用上面的链接导航到游乐场。

  2. 点击右上角的设置按钮。

  3. 选择“服务器端”作为“OAuth流程”,选择“自定义”作为“OAuth端点”。

  4. 在授权端点中,输入授权控制器的URL(例如https://domain.com/authorize.php)。

  5. 在令牌端点中,输入令牌控制器的URL(例如https://domain.com/token.php)。

  6. 为访问令牌位置选择“授权标头w /承载前缀”。

  7. 输入客户端ID和密码(如果使用以前的文档示例,则使用testclient和testpass)。

  8. 在左侧的文本框中输入“basic”,然后单击“授权API”。你应该被带到你的网站,你可以授权请求,之后你应该返回到游乐场。

  9. 点击“兑换令牌授权码”即可接收令牌(您需要在30秒内完成)。

  10. 在右边的回应应该显示访问令牌。输入资源页面的URL(例如https://domain.com/resource.php)。

  11. 添加你想要的任何可选参数,然后点击“发送请求”。如果您以前使用过相同的代码,则应该看到相同的响应:

json
{"success":true,"message":"You accessed my APIs!"}

Drupal的

对于drupal集成,请参阅bojanz的OAuth2服务器模块。

Zend框架

为了这个库与Zend框架2整合,你可以使用这些模块之一:*OAuth2Provider由弗兰茨·德利恩*ZF2-的oauth2提供商由格伦·施密特

Laravel

在Laravel 4中查看这个Laravel演示应用程序来实现这个库。

一步一步的演练

  1. 创建你的Laravel项目(例如composer create-project laravel/laravel --prefer-dist
  2. 使用Composer:composer require bshaffer/oauth2-server-php和安装OAuth2服务器和HTTPFoundation网桥依赖关系composer require bshaffer/oauth2-server-httpfoundation-bridge
  3. 设置您的数据库并运行提供的迁移(请参阅https://github.com/julien-c/laravel-oauth2-server/commit/b290d4f699b9758696444e2d62dd82f0eeedcb7d):

    php artisan db:migrate

  4. 使用提供的脚本对数据库进行种子处理:https://github.com/julien-c/laravel-oauth2-server/commit/8895c54cbf8ea8ba78aafab53a5a0409ce2f1ba2

    php artisan db:seed

  5. 设置您的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;});
  1. 实施您希望实施的实际OAuth2控制器。例如令牌控制器和资源控制器:请参阅app/routes.php

你甚至可以单元测试你的整合!下面是一个使用Guzzle的例子:https://github.com/julien-c/laravel-oauth2-server/blob/master/app/tests/OAuthTest.php

教义

创建客户端和访问令牌存储

要把学说融入到你的项目中,首先要建立你的模型。我们先从客户端和访问令牌模型开始:

yaml
OAuthClient: ?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

一旦你从这个模式中生成模型,你将有一个OAuthClientOAuthCleintTable类文件,以及一个OAuthAccessTokenOAuthAccessTokenTable对象。

OAuth2\Storage\ClientCredentialsInterfaceOAuthClientTable课堂上实施:

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\AccessTokenInterfaceOAuthAccessTokenTable课堂上实施:

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_credentialsaccess_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: ????CASCADEOAuthRefreshToken: ?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\AuthorizationCodeInterfaceOAuth2\Storage\RefreshTokenInterface。这将允许我们使用他们的对应授权类型。

OAuth2\Storage\AuthorizationCodeInterfaceOAuthAuthorizationCodeTable课堂上实施:

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\RefreshTokenInterfaceOAuthRefreshTokenTable课堂上实施:

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 食谱

原文地址:http://www.cnblogs.com/endv/p/7842520.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved