自己动手:实现OAuth2.0
前段时间写了篇文章关于如何使用laravel的oauth2.0功能,现在突然有些手痒,索性自己来实现一个玩具,也好更加了解oauth
阅读本文需要如下技能:
PHP:一般
OAuth:一般
Redis:初学
HTML:初学
如果对oauth不熟悉,建议阅读阮一峰先生的文章:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
首先,准备一个最简单的文件,index.php,然后里面只要能够登陆与已已登录验证的功能就行,这是我的代码,超级简陋,但是能用
if (isset($_GET['action']) && $_GET['action'] === 'login')
setcookie('isLogined', 'true', 0, "/");
$msg = isset($_COOKIE['isLogined']) && $_COOKIE['isLogined'] === 'true'
? '已登陆' : '未登录';
if (isset($_GET['token']) && $_GET['token'] === $redis->get('token'))
$msg = '这是经过验证后的数据,绝密!';
echo "
$msg
<a href="index.php?action=login">登陆</a>
";
ok,现在这是一个最基本的界面
下面开始实现让用户点击授权的界面
这是我的代码
authorize.php
$redis = new Redis();
$redis->connect('127.0.0.1', '6379');
$code = random_int(10000, 20000);
$redis->set('code', $code, 60);
$redirectUrl = $_GET['redirectUrl'];
echo "
申请权限,是否同意?
<a href="$redirectUrl?code=$code">同意</a>
<a href="$redirectUrl?code=">拒绝</a>
";
东西看上去有点多,不过并不复杂,这里采用了redis存储中途要用到的code,并将过期时间设置为60秒
打开这个界面是这个样子的
ok,没有问题,如果用户点击同意,那么code将被会传进客户端的redirectUrl中,否则就不会传递
由于这个页面是服务器显示出来的,所以基本不用担心非用户操作
下面来编写客户端的回调处理,这个回调需要完成用code去服务器换取token并存储的功能
代码如下:
callback.php
$errorMsg = '';
if (!isset($_GET['code']) || $_GET['code'] === '')
$errorMsg = '你拒绝了权限申请';
else
{
$url = "http://192.168.100.104/token.php?" . http_build_query(['code' => $_GET['code']]);
// 向后台服务器用code换取token
$http = curl_init($url);
curl_setopt($http, CURLOPT_TIMEOUT, 10);
curl_setopt($http, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($http);
if ($result === '')
$errorMsg = "code不正确";
if (curl_errno($http))
$errorMsg = curl_error($http);
}
echo "$errorMsg";
echo $errorMsg;
echo $result;
curl_close($http);
if (empty($errorMsg))
header("Location: index.php?token=$result");
这一步是不是有些晕,看得迷糊?没关系,其实这一步应该是倒数第二步
下面来实现token服务器的代码,它需要完成验证客户端传递过来的code(在实际情况下还会验证客户端的有效性),并返回可用的token
token.php
$redis = new Redis();
$redis->connect('127.0.0.1', '6379');
$token = '';
if (isset($_GET['code']) && $redis->get('code') === $_GET['code'])
{
// 验证成功
try
{
$token = md5(random_int(100, 3000));
$redis->set('token', $token);
} catch (Exception $e)
{
}
}
echo $token;
接下来,访问 你的域名/authorize.php?redirectUrl=callback.php,点击同意,查看显示结果,如何?理解了么?
没有理解也没有关系,我会详细解释,如果有什么不理解的,请对照上面的代码
这是阮一峰先生文章上步骤的截图,我们按照这个顺序一步一步来
(A)访问 你的域名/authorize.php?redirectUrl=callback.php
(B)点击同意
(C)同意后会跳转到 你的域名/callback.php?code=xxxx,接下来客户端回调向服务器申请令牌,通过curl,向token.php传递code参数,请求令牌
(D)这步来到了token.php中,主要就是验证code是否合法,然后发放令牌
(E)回调中这时已经获取了token,接下来是向资源服务器(这里是index.php)获取资源,带上刚刚获取的token
(F)回到index.php中,关注第7、8两行,这里验证token
这就是整个流程,当然实际中不止这么简单,但大体都是一样,像微信开发中的验证,也是如此。
如果仍然有什么不理解的,可以留下你的评论。
最后附上代码文件oauth.zip