php oauth 客户端和服务端流程与实现
介绍:
1、主要用于第三方获取用户资源 普遍用于第三方登录授权获取用户信息
2、是一种协议RFC-5849(不是软件或服务)
3、认证+授权
oauth2-server
流程图:
各平台流程图
163 | 开心网 | 新浪微博 |
---|---|---|
客户端与服务端实现:
1、由流程图我们可以看出需要以下几步 0、获取用户Key与Secret(流程图之外)【server/create_consumer.php】
1、获取Request Token 与 Request Secret 【client/get_request_token.php】
2、返回Request Token 与 Request Secret 【server/request_token.php】
3、重定向授权页 ——|
【server/authorize.php】
4、用户授权回调 ——|
5、获取Access Token 与 Access Secret 【client/get_access_token.php】
6、返回Access Token 与 Access Secret 【server/access_token.php】
7、调用api(流程图之外)【client/get_api.php】
8、返回api获取的数据(流程图之外)【server/api.php】
代码目录结构
2、代码实现流程
0:server/create_consumer.php客户端生成consumer key与consumer secret
<?php
echo 'Consumer key: ' . sha1(OAuthProvider::generateToken(40));
echo '<br/>';
echo 'Consumer secret: ' . sha1(OAuthProvider::generateToken(40));
OAuthProvider : OAuth提供者类
generateToken :生成一个随机令牌
generateToken这个函数需要注意性能我们注意第二个参数 dev/random 与 dev/urandom性能上有区分 此处不做详细说明请根据自己项目调优
具体性能信息请参考:/dev/random Mcrypt响应慢的一个原因
sha1:使用HMAC-SHA1算法生成签名
百度:OAuth请求可以使用HMAC-SHA1或MD5算法生成签名。
新浪微博:OAuth请求都使用HMAC-SHA1算法生成签名
运行结果
1:client/get_request_token.php 获取Request Token 与 Request Secret
<?php
$consumer_key = '2b4e141bf09beecdeb3479cd106038100febf399';
$consumer_secret = 'fab40ca819c25d5fb4abf3e7cae8da5c25b67d05';
$request_url = 'http://localhost/test/server/request_token.php';//获取服务器request_token地址
$callback_url = 'http://localhost/test/client/get_access_token.php';//回调本地地址
$authorize_url = 'http://localhost/test/server/authorize.php';//服务端授权验证地址
$oauth = new OAuth($consumer_key, $consumer_secret);
//获取到
//oauth_token指的是request_token
//oauth_token_secret指的是request_secret
//scope 申请权限所需参数 all或无此参数默认是所有权限
$token_info = $oauth->getRequestToken($request_url . '?callback_url=' . $callback_url . '&scope=all');
session_start();
$_SESSION['oauth_token_secret'] = $tokenInfo['oauth_token_secret'];
//此时重定向到服务端授权并显示给用户
header('Location: '.$authorize_url.'?oauth_token=' . $token_info['oauth_token']);
?>
以上代码我们会通过
getRequestToken($request_url . '?callback_url=' . $callback_url . '&scope=all')运行服务端代码
2:server/request_token.php 返回 request_token
<?php
$oauth_token = sha1(OAuthProvider::generateToken(40));
$oauth_token_secret = sha1(OAuthProvider::generateToken(40));
//oauth_callback_confirmed:对oauth_callback的确认信号 (true/false)
echo "oauth_token=$oauth_token&oauth_token_secret=$oauth_token_secret&oauth_callback_confirmed=true";
通过2中的代码1获取到$oauth_token与$oauth_token_secret与oauth_callback_confirmed
之后重定向到3
3:server/authorize.php
授权验证 此处应该是需要用户输入账号密码之后再回调的我为了代码最基本实现省略了用户之间默认授权
<?php
$callback_url = 'http://localhost/test/client/get_access_token.php';//回调本地地址
header('location: '.$callback_url.'?oauth_token=' . $_REQUEST['oauth_token']);
此处校验是简略的 默认已经授权直接获第三方回调地址 (正常情况是用户授权后服务端通过数据库获取第三方回调地址并把 oauth_token授权了 之前oauth_token一直是未授权状态)
上面代码通过回调地址把已经授权的request_token(oauth_token)传到5(4用户授权此处掠过自己可以加个表单提交作为授权验证)
5:client/get_access_token.php 获取access token
<?php
$consumer_key = '2b4e141bf09beecdeb3479cd106038100febf399';
$consumer_secret = 'fab40ca819c25d5fb4abf3e7cae8da5c25b67d05';
$access_url = 'http://localhost/test/server/access_token.php';//获取服务器access_token地址
$OAuth = new OAuth($consumer_key, $consumer_secret);
$OAuth->setToken($_GET['oauth_token'], $_SESSION['oauth_token_secret']);
$tokenInfo = $OAuth->getAccessToken($access_url);
var_dump($tokenInfo);
$tokenInfo = $OAuth->getAccessToken($access_url);方法问了6
6:server/access_token.php 返回access token
<?php
$access_token = sha1(OAuthProvider::generateToken(40));
$access_secret = sha1(OAuthProvider::generateToken(40));
echo "access_token=$access_token&access_secret=$access_secret";
2:get_request_token一直到6:server/access_token.php流程
获取request_token——》返回request_token——》用户授权校验authorize——》校验成功回调——》获取access token——》返回access token
运行结果如下
一直重定向到get_access_token并获取了access_token与access_secret
现在我们客户端(第三方平台)获取了如下数据
$consumer_key :2b4e141bf09beecdeb3479cd106038100febf399
$consumer_secret :fab40ca819c25d5fb4abf3e7cae8da5c25b67d05
$request_token :?程序中间数据(此数据一般是有时效的)
$request_secret :?程序中间数据(此数据一般是有时效的)
$access_token :12b6f8f6d6930e0e4d1d024c0f520527d0b84d19 (此数据一般时效为无限长)
$access_secret :c77463aff2c1abbd670cfb03df4bb4247910cb78 (此数据一般时效为无限长)
现在我们通过这些参数运行7:get_api.php到8:api.php
7:client/get_api.php 获取api用户数据
<?php
$consumer_key = '2b4e141bf09beecdeb3479cd106038100febf399';
$consumer_secret = 'fab40ca819c25d5fb4abf3e7cae8da5c25b67d05';
$access_token = '12b6f8f6d6930e0e4d1d024c0f520527d0b84d19';
$access_secret = 'c77463aff2c1abbd670cfb03df4bb4247910cb78';
$api_url='http://localhost/test/server/api.php';
$OAuth = new OAuth($consumer_key, $consumer_secret);
$OAuth->setToken($access_token, $access_secret);
$result = $OAuth->fetch($api_url, array(), OAUTH_HTTP_METHOD_POST);
echo $OAuth->getLastResponse();
8:server/api.php 返回用户数据
<?php
function consumerHandler($Provider) {
$Provider->consumer_secret = 'fab40ca819c25d5fb4abf3e7cae8da5c25b67d05';
return OAUTH_OK;
}
function timestampNonceHandler($Provider) {
return OAUTH_OK;
}
function tokenHandler($Provider) {
$Provider->token = '12b6f8f6d6930e0e4d1d024c0f520527d0b84d19';
$Provider->token_secret = 'c77463aff2c1abbd670cfb03df4bb4247910cb78';
return OAUTH_OK;
}
$OAuthProvider = new OAuthProvider();
$OAuthProvider->consumerHandler('consumerHandler');
$OAuthProvider->timestampNonceHandler('timestampNonceHandler');
$OAuthProvider->tokenHandler('tokenHandler');
try {
$OAuthProvider->checkOAuthRequest();
} catch (Exception $exc) {
die(var_dump($exc));
}
echo 'User Data..';
运行结果
注:php oauth v1.0 配置 后并开启 php_curl 才能运行此(以上)代码