oauth2.0-server-php的授权码模式的使用

一、oauth的授权码模式
这里引用了阮一峰的oauth的文章的部分内容,传送门
步骤:
1、A.com向B.com请求获取授权码
2、B.com返回授权码给A.com
3、A.com用授权码向B.com获取令牌
4、B.com返回令牌给A.com
5、使用令牌获取数据资源

第一步,A 网站提供一个链接,用户点击后就会跳转到 B 网站,授权用户数据给 A 网站使用。下面就是 A 网站跳转 B 网站的一个示意链接。

https://b.com/oauth/authorize?
  response_type=code&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

上面 URL 中,response_type参数表示要求返回授权码(code),client_id参数让 B 知道是谁在请求,redirect_uri参数是 B 接受或拒绝请求后的跳转网址,scope参数表示要求的授权范围(这里是只读)。执行成功后,B.com往数据库的oauth_authorization_codes写入对应数据
在这里插入图片描述
第二步,用户跳转后,B 网站会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时 B 网站就会跳回redirect_uri参数指定的网址。跳转时,会传回一个授权码,就像下面这样。

https://a.com/callback?code=AUTHORIZATION_CODE

上面 URL 中,code参数就是授权码。
在这里插入图片描述
第三步,A 网站拿到授权码以后,就可以在后端,向 B 网站请求令牌。

https://b.com/oauth/token?
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET&
 grant_type=authorization_code&
 code=AUTHORIZATION_CODE&
 redirect_uri=CALLBACK_URL

上面 URL 中,client_id参数和client_secret参数用来让 B 确认 A 的身份(client_secret参数是保密的,因此只能在后端发请求),grant_type参数的值是AUTHORIZATION_CODE,表示采用的授权方式是授权码,code参数是上一步拿到的授权码,redirect_uri参数是令牌颁发后的回调网址。
在这里插入图片描述
第四步,B 网站收到请求以后,就会颁发令牌。具体做法是向redirect_uri指定的网址,发送一段 JSON 数据。


{    
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,
  "refresh_token":"REFRESH_TOKEN",
  "scope":"read",
  "uid":100101,
  "info":{...}
}

上面 JSON 数据中,access_token字段就是令牌,A 网站在后端拿到了。
在这里插入图片描述

二、开干

  1. 下载oauth-server-php:
    git clone https://github.com/bshaffer/oauth2-server-php.git -b master
    存放到根目录

2.安装数据库
执行以下sql语句:


--
-- Database: `oauth2db`
--

-- --------------------------------------------------------

--
-- 表的结构 `oauth_access_tokens`
--

CREATE TABLE IF NOT EXISTS `oauth_access_tokens` (
  `access_token` varchar(40) NOT NULL,
  `client_id` varchar(80) NOT NULL,
  `user_id` varchar(255) DEFAULT NULL,
  `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `scope` varchar(2000) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- 表的结构 `oauth_authorization_codes`
--

CREATE TABLE IF NOT EXISTS `oauth_authorization_codes` (
  `authorization_code` varchar(40) NOT NULL,
  `client_id` varchar(80) NOT NULL,
  `user_id` varchar(255) DEFAULT NULL,
  `redirect_uri` varchar(2000) DEFAULT NULL,
  `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `scope` varchar(2000) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- 表的结构 `oauth_clients`
--

CREATE TABLE IF NOT EXISTS `oauth_clients` (
  `client_id` varchar(80) NOT NULL,
  `client_secret` varchar(80) NOT NULL,
  `redirect_uri` varchar(2000) NOT NULL,
  `grant_types` varchar(80) DEFAULT NULL,
  `scope` varchar(100) DEFAULT NULL,
  `user_id` varchar(80) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- 转存表中的数据 `oauth_clients`
--

INSERT INTO `oauth_clients` (`client_id`, `client_secret`, `redirect_uri`, `grant_types`, `scope`, `user_id`) VALUES
('testclient', 'testpass', 'https://user.endv.cn/', 'authorization_code', '', '');

-- --------------------------------------------------------

--
-- 表的结构 `oauth_jwt`
--

CREATE TABLE IF NOT EXISTS `oauth_jwt` (
  `client_id` varchar(80) NOT NULL,
  `subject` varchar(80) DEFAULT NULL,
  `public_key` varchar(2000) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- 表的结构 `oauth_refresh_tokens`
--

CREATE TABLE IF NOT EXISTS `oauth_refresh_tokens` (
  `refresh_token` varchar(40) NOT NULL,
  `client_id` varchar(80) NOT NULL,
  `user_id` varchar(255) DEFAULT NULL,
  `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `scope` varchar(2000) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- 表的结构 `oauth_scopes`
--

CREATE TABLE IF NOT EXISTS `oauth_scopes` (
  `scope` text,
  `is_default` tinyint(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- 表的结构 `oauth_users`
--

CREATE TABLE IF NOT EXISTS `oauth_users` (
  `username` varchar(255) NOT NULL,
  `password` varchar(2000) DEFAULT NULL,
  `first_name` varchar(255) DEFAULT NULL,
  `last_name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3、写入数据到数据库
添加客户端到表:oauth_clients,只有添加到该表到客户端才可以获取授权码

+------------+---------------+-------------------+--------------------+-------+---------+
| client_id  | client_secret | redirect_uri      | grant_types        | scope | user_id |
+------------+---------------+-------------------+--------------------+-------+---------+
| testclient | testpass      | http://127.0.0.1/ | authorization_code |       |         |
+------------+---------------+-------------------+--------------------+-------+---------+

4、配置server服务
在根目录新建server.php文件,代码如下:

<?php
  /** 配置 */
$dsn= 'mysql:dbname=test;host=localhost';
$username = 'test';
$password = 'test';

// 错误报告(这毕竟是一个演示!)
ini_set('display_errors',1);error_reporting(E_ALL);

// 自动加载
require_once('oauth2-server-php/src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();
$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));

// 通过存储对象或对象数组存储的oauth2服务器类
$server = new OAuth2\Server($storage);

// 授权码 有效期只有30秒
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage));

// 客户端证书
$server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage));

// 用户凭据
$server->addGrantType(new OAuth2\GrantType\UserCredentials($storage));
// 刷新令牌  启用这个会报错,原因未知
// $server->addGrantType(new OAuth2\GrantType\RefreshToken($refreshStorage))

注意:数据库的配置信息根据自己的配置进行操作

5、获取授权码
参考oauth的授权码模式的使用的第一步。A网站向B网站请求授权码,B网站生成授权码并写入表oauth_authorization_codes中,然后返回给A网站

6、使用授权码获取令牌
创建token.php文件,代码如下:

<?php
 // include our OAuth2 Server object
require_once __DIR__.'/server.php';
 
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();

然后执行指令:

curl -u testclient:testpass http://127.0.0.1/token.php --data "grant_type=authorization_code&code=你的授权码"

执行成功后则会返回数据:

{"access_token":"84c66d296308aad20aa5e065743d2fe30426b046","expires_in":3600,"token_type":"Bearer","scope":null,"refresh_token":"d49cd4d7d875065888fc457c7c714cab9fcf9d69"}

7、使用token获取数据
创建resource.php文件,代码如下:

<?php
 
 //资源控制器的建立和测试 
require_once __DIR__.'/server.php';

if (!$server->verifyResourceRequest(OAuth2\Request::createFromGlobals())) {
    $server->getResponse()->send();
    die;
}
$token = $server->getAccessTokenData(OAuth2\Request::createFromGlobals());
echo "User ID associated with this token is {$token['user_id']}";

echo json_encode(array('success' => true, 'message' => '您访问了我的API!'));

执行指令:

curl https://127.0.0.1/resource.php --data 'access_token=YOUR_TOKEN'

在这个resource.php文件中可以根据token的正确性来决定是否返回相应的数据给请求方。
以上仅供参考,如有错误,望各位指正。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值