oauth2-server-php-docs 食谱
一步一步的演练
以下说明提供详细的演练,以帮助您启动并运行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
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 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客户端:
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”虚拟主机来指向它。这可能会因您的应用程序而异。
如果一切正常,你应该收到这样的回应:
{"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
如果一切顺利的话,你应该会收到这样的回复:
{"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'
和以前一样,您将收到一个访问令牌:
{"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)。
添加你想要的任何可选参数,然后点击“发送请求”。如果您以前使用过相同的代码,则应该看到相同的响应:
{"success":true,"message":"You accessed my APIs!"}
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
教义
创建客户端和访问令牌存储
要把学说融入到你的项目中,首先要建立你的模型。我们先从客户端和访问令牌模型开始:
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
一旦你从这个模式中生成模型,你将有一个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();
添加授权码和刷新令牌存储----------------
所以让我们的应用程序更加精彩一点。将以下内容添加到您的模式并生成类文件:
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 在 Yii 框架上搭建 OAuth2 Server
原文转自 http://www.cnblogs.com/ldms/p/4565547.html Yii 有很多 extension 可以使用,在查看了 Yii 官网上提供的与 OAuth 相关的扩展后 ...
- 使用 OAuth2-Server-php 搭建 OAuth2 Server
Yii 有很多 extension 可以使用,在查看了 Yii 官网上提供的与 OAuth 相关的扩展后,发现了几个 OAuth2 的客户端扩展,但是并没有找到可以作为 OAuth2 Server 的 ...
- CAS3.5.x(x>1)支持OAuth2 server
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- 开始使用 Docker (Linux 上运行 SQL Server) 上的 SQL Server 容器 - SQL Server | Microsoft Docs
原文:开始使用 Docker (Linux 上运行 SQL Server) 上的 SQL Server 容器 - SQL Server | Microsoft Docs 快速入门:使用 Docker ...
- 使用ms owin 搭建oauth2 server
http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server 有示例代码 关于token的 ...
- PHP OAuth2 Server库
想找比较正宗的库,查了蛮久的.最后在 oauth官方站上,看到PHP版本的相关链接. 发现都是php 5.3版本以上的环境,基于命名空间的写法编写的. 访问下面这个页面,难得,发现文档给出了5.2版本 ...
- 微服务下前后端分离的统一认证授权服务,基于Spring Security OAuth2 + Spring Cloud Gateway实现单点登录
1. 整体架构 在这种结构中,网关就是一个资源服务器,它负责统一授权(鉴权).路由转发.保护下游微服务. 后端微服务应用完全不用考虑权限问题,也不需要引入spring security依赖,就正常的 ...
- 每周开源项目分享-年轻人的第一个OAuth2.0 Server:hydra
年轻人的第一个OAuth2.0 Server:hydra hydra 是什么呢? OpenID Connect certified OAuth2 Server - cloud native, secu ...
- 使用OAuth Server PHP实现OAuth2服务
在现在的网络服务中,OAuth2.0服务已经很普遍了,无论是facebook或者微博的第三方登录,还是手机APP登录,都有很广泛的应用.它主要的目的如下:如果用户的照片在A网站,他想要在B网站使用A网 ...
- OAuth2实现单点登录SSO
1. 前言 技术这东西吧,看别人写的好像很简单似的,到自己去写的时候就各种问题,“一看就会,一做就错”.网上关于实现SSO的文章一大堆,但是当你真的照着写的时候就会发现根本不是那么回事儿,简直让人抓 ...
随机推荐
- WebClient 通过get和post请求api
//get 请求 string url = string.Format("http://localhost:28450/api/values?str1=a&str2=b ...
- Promise,Generator(生成器),async(异步)函数
Promise 是什么 Promise是异步编程的一种解决方案.Promise对象表示了异步操作的最终状态(完成或失败)和返回的结果. 其实我们在jQuery的ajax中已经见识了部分Promise的 ...
- 咏南中间件开始支持redis client接口调用
咏南中间件开始支持redis client接口调用 咏南中间件封装了redis client接口,可以支持REDIS了. 如下图,将数据集写入REDIS缓存,和从REDIS缓存获取数据: proced ...
- iOS非ARC内存管理摘要 - 实践型
关于ios内存管理.在开发过程中,内存管理很重要,我简单说明一下. 1.正确用法 UIView *v = [[UIView alloc] init]; //分配后引用计数为1 [self.view a ...
- C#编程(四十四)----------string和stringbuilder
System.String类 首先string类是静态的,System.String是最常用的字符串操作类,可以帮助开发者完成绝大部分的字符串操作功能,使用方便. 1.比较字符串 比较字符串是指按照字 ...
- arcmap搜索脚本错误
C盘/windows/temp,将temp文件夹右键单击,选择属性>选择安全>编辑>AlL APPLICATION PACKAGES>确定>关闭,如是操作即可解决 在cu ...
- .NET:不要使用扩展方法扩展Object对象。
C#的扩展方法算是一种Minin(掺入)机制,掺入方法有其合理的使用场景,这里说说一种不好的使用场景(个人意见):不要使用扩展方法扩展Object对象.扩展Object会对所有类型的示例有侵入,特别是 ...
- Storm实时计算系统
来自知乎: 伴随着信息科技日新月异的发展,信息呈现出爆发式的膨胀,人们获取信息的途径也更加多样.更加便捷,同时对于信息的时效性要求也越来越高.举个搜索场景中的例子,当一个卖家发布了一条宝贝信息时,他希 ...
- 【转】Android思维导图
转自:http://www.open-open.com/lib/view/open1421201191375.html
- SpringBoot 获取当前登录用户IP
控制器方法: @RequestMapping(value = "/getIp", method = RequestMethod.POST) @ResponseBody public ...