维基百科里有很好的说明 http://zh.wikipedia.org/wiki/OAuth
现在OAuth2.0协议的应用已经非常广泛,比如我们常用到的在团购网或论坛上用qq号或者微博账号直接登录,就是用OAuth2.0协议实现的.
按照以上流程,OAuth2.0协议的服务端和客户端实现并不困难,一个一般水平的程序员完全可以自己编写~
如果不愿自己花精力,可以使用网上的开源类库.
本次测试使用的服务端类库下载地址:http://code.google.com/p/oauth2-php/
测试可以在同一域名下进行,也可以在不同域名下进行,因为服务端可以不用session和cookie,不涉及到域的问题.
此服务端支持mysql和mongodo两种数据库,本次测试使用mysql数据库,数据库连接扩展需要用pdo_mysql.
为了让测试结果更加直观,服务端域名用server.com客户端域名用client.com
include "../../../lib/oauth.php";
这个引用地址不对,要改成
include '../../../lib/OAuth2.inc';
这样服务端就搭建完成了.
由于是第一次使用OAuth2.0协议,我对它不是很熟悉,写客户端费了不少功夫.
主要参考的是腾讯网的调用说明:http://wiki.opensns.qq.com/wiki/%E3%80%90QQ%E7%99%BB%E5%BD%95%E3%80%91%E5%BC%80%E5%8F%91%E6%94%BB%E7%95%A5_Server-side
测试不通的时候就在客户端代码中加断点调试.这个服务端的报错不是很友好,但代码很容易看懂.
访问http://server.com/oauth2-php/server/examples/pdo/addclient.php 注册客户端.
客户端id和密钥需要写长一些,最短3个字符,否则验证时会出错.
Redirect URI这一项可以填写http://client.com,它必须是客户端所有数据传送页面地址的前缀,所以不能写成http://client.com/index.php这样.
<?php error_reporting ( E_ALL - E_NOTICE ); session_start (); // 应用的APPID $app_id = "1111111111"; // 应用的APPKEY $app_secret = "2222222222";
<?php include("common.php"); // 成功授权后的回调地址 $my_url = "http://client.com/step2.php"; // Step1:获取Authorization Code $code = $_REQUEST ["code"]; if (empty ( $code )) { // state参数用于防止CSRF攻击,成功授权后回调时会原样带回 $_SESSION ['state'] = md5 ( uniqid ( rand (), TRUE ) ); // 拼接URL $dialog_url = "http://server.com/oauth2-php/server/examples/pdo/authorize.php?response_type=code&client_id=" . $app_id . "&redirect_uri=" . urlencode ( $my_url ) . "&state=" . $_SESSION ['state']; echo ("<script> top.location.href='" . $dialog_url . "'</script>"); }
<?php include("common.php"); // 接收上一步返回的错误信息 if ($_REQUEST ['error']) die ( $_REQUEST ['error'] ); // 用于发送post请求的方法,取得访问令牌需要用post请求 function http_post($url, $data) { $data_url = http_build_query ( $data ); $data_len = strlen ( $data_url ); return array ('content' => file_get_contents ( $url, false, stream_context_create ( array ('http' => array ('method' => 'POST', 'header' => "Connection: close\r\nContent-Length: $data_len\r\n", 'content' => $data_url ) ) ) ), 'headers' => $http_response_header ); } // code是服务端返回的临时令牌 $code = $_REQUEST ["code"]; // Step2:通过Authorization Code获取Access Token if ($_REQUEST ['state'] == $_SESSION ['state']) { $re = http_post ( "http://server.com/oauth2-php/server/examples/pdo/token.php", array ( 'client_id' => $app_id, 'client_secret' => $app_secret, 'code' => $code, 'grant_type' => 'authorization_code', // redirect_uri一定要是当前页面的地址,否则会认证失败 'redirect_uri' => 'http://client.com/step2.php' ) ); $re = ( array ) json_decode ( $re ['content'] ); if($re['access_token']) { $_SESSION['access_token']=$re ['access_token']; echo "访问令牌是:".$re ['access_token'],"<br /><a href='step3.php'>访问受保护的资源</a>"; } else { echo "获取令牌失败!"; } }
<?php include("common.php"); //资源地址 $url = "http://server.com/oauth2-php/server/examples/pdo/protected_resource.php". "?oauth_token=" . $_SESSION['access_token']; //获取到的受保护资源内容 if($content = file_get_contents ( $url )) echo "以下是获取到的受保护内容:<br />",$content; else echo "获取资源失败!";
搭建完成后访问客户端的step1.php,http://client.com/step1.php进行测试