您好,欢迎访问一九零五行业门户网

基于ThinkPHP框架筹建OAuth2.0服务

基于thinkphp框架搭建oauth2.0服务
这几天一直在搞oauth2.0的东西,写sdk啥的,为了更加深入的了解服务端的oauth验证机制,就自己动手搭了个php下oauth的环境,并且将它移植到了自己比较熟的tp框架里。
废话不少说,开动。
?
其实网上是有oauth2.0的php版本的。
你可以在http://code.google.com/p/oauth2-php/?找到源代码,上面实现了pdo和mongodb的数据模式。这里我也是基于这些代码在tp中进行整合的。
?
好,这里我们可以把下载下来的包解压,把lib下的oauth.inc改名为oauth2.class.php后放到tp核心包下的目录下:
?
/extend/library/org/oauth/oauth2.class.php
?
接下来我们要继承这个类;
在这个目录下新建一个thinkoauth2.class.php文件:
?
db = db::getinstance(c('oauth2_db_dsn')); $this -> table = array( 'auth_codes'=>c('oauth2_codes_table'), 'clients'=>c('oauth2_clients_table'), 'tokens'=>c('oauth2_token_table') ); } /** * 析构 */ function __destruct() { $this->db = null; // release db connection } private function handleexception($e) { echo database error: . $e->getmessage(); exit; } /** * * 增加client * @param string $client_id * @param string $client_secret * @param string $redirect_uri */ public function addclient($client_id, $client_secret, $redirect_uri) { $time = time(); $sql = insert into {$this -> table['clients']} . (client_id, client_secret, redirect_uri, create_time) values (\{$client_id}\, \{$client_secret}\, \{$redirect_uri}\,\{$time}\); $this -> db -> execute($sql); } /** * implements oauth2::checkclientcredentials() * @see oauth2::checkclientcredentials() */ protected function checkclientcredentials($client_id, $client_secret = null) { $sql = select client_secret from {$this -> table['clients']} . where client_id = \{$client_id}\; $result = $this -> db -> query($sql); if ($client_secret === null) { return $result !== false; } //log::write(checkclientcredentials : .$result); //log::write(checkclientcredentials : .$result[0]); //log::write(checkclientcredentials : .$result[0][client_secret]); return $result[0][client_secret] == $client_secret; } /** * implements oauth2::getredirecturi(). * @see oauth2::getredirecturi() */ protected function getredirecturi($client_id) { $sql = select redirect_uri from {$this -> table['clients']} . where client_id = \{$client_id}\; $result = $this -> db -> query($sql); if ($result === false) { return false; } //log::write(getredirecturi : .$result); //log::write(getredirecturi : .$result[0]); //log::write(getredirecturi : .$result[0][redirect_uri]); return isset($result[0][redirect_uri]) && $result[0][redirect_uri] ? $result[0][redirect_uri] : null; } /** * implements oauth2::getaccesstoken(). * @see oauth2::getaccesstoken() */ protected function getaccesstoken($access_token) { $sql = select client_id, expires, scope from {$this -> table['tokens']} . where access_token = \{$access_token}\; $result = $this -> db -> query($sql); //log::write(getaccesstoken : .$result); //log::write(getaccesstoken : .$result[0]); return $result !== false ? $result : null; } /** * implements oauth2::setaccesstoken(). * @see oauth2::setaccesstoken() */ protected function setaccesstoken($access_token, $client_id, $expires, $scope = null) { $sql = insert into {$this -> table['tokens']} . (access_token, client_id, expires, scope) . values (\{$access_token}\, \{$client_id}\, \{$expires}\, \{$scope}\); $this -> db -> execute($sql); } /** * overrides oauth2::getsupportedgranttypes(). * @see oauth2::getsupportedgranttypes() */ protected function getsupportedgranttypes() { return array( oauth2_grant_type_auth_code ); } /** * overrides oauth2::getauthcode(). * @see oauth2::getauthcode() */ protected function getauthcode($code) { $sql = select code, client_id, redirect_uri, expires, scope . from {$this -> table['auth_codes']} where code = \{$code}\; $result = $this -> db -> query($sql); //log::write(getauthcode : .$result); //log::write(getauthcode : .$result[0]); //log::write(getauthcode : .$result[0][code]); return $result !== false ? $result[0] : null; } /** * overrides oauth2::setauthcode(). * @see oauth2::setauthcode() */ protected function setauthcode($code, $client_id, $redirect_uri, $expires, $scope = null) { $time = time(); $sql = insert into {$this -> table['auth_codes']} . (code, client_id, redirect_uri, expires, scope) . values (\${code}\, \${client_id}\, \${redirect_uri}\, \${expires}\, \${scope}\); $result = $this -> db -> execute($sql); } /** * overrides oauth2::checkusercredentials(). * @see oauth2::checkusercredentials() */ protected function checkusercredentials($client_id, $username, $password){ return true; }}
?
?在这里我们需要创建数据库:
?
create table `oauth_client` ( `id` bigint(20) not null auto_increment, `client_id` varchar(32) not null, `client_secret` varchar(32) not null, `redirect_uri` varchar(200) not null, `create_time` int(20) default null, primary key (`id`)) engine=myisam auto_increment=3 default charset=utf8;create table `oauth_code` ( `id` bigint(20) not null auto_increment, `client_id` varchar(32) not null, `user_id` varchar(32) not null, `code` varchar(40) not null, `redirect_uri` varchar(200) not null, `expires` int(11) not null, `scope` varchar(250) default null, primary key (`id`)) engine=myisam default charset=utf8;create table `oauth_token` ( `id` bigint(20) not null auto_increment, `client_id` varchar(32) not null, `user_id` varchar(32) not null, `access_token` varchar(40) not null, `refresh_token` varchar(40) not null, `expires` int(11) not null, `scope` varchar(200) default null, primary key (`id`)) engine=myisam auto_increment=2 default charset=utf8;
??
上面的数据库表名可以自己随便定;但是要在config.php配置表名:
?
'oauth2_codes_table'=>'oauth_code','oauth2_clients_table'=>'oauth_client','oauth2_token_table'=>'oauth_token',
?
如果oauth的服务器不是当前服务器,那就要指定下dsn地址了:
?
?
'oauth2_db_dsn'=>'mysql://root:mima@l:3306/database'
?
?
好了,大致的核心库代码就是如此。接下来要使用它
?
我们创建一个oauth的action负责oauth2的一些验证(oauthaction.class.php)
?
import(org.oauth.thinkoauth2);class oauthaction extends action { private $oauth = null; function _initialize(){ header(content-type: application/json); header(cache-control: no-store); $this -> oauth = new thinkoauth2(); } public function index(){ header(content-type:application/json; charset=utf-8); $this -> ajaxreturn(null, 'oauth-server-start', 1, 'json'); } public function access_token() { $this -> oauth -> grantaccesstoken(); } //权限验证 public function authorize() { if ($_post) { $this -> oauth -> finishclientauthorization($_post[accept] == yep, $_post); return; } ///表单准备 $auth_params = $this -> oauth -> getauthorizeparams(); $this -> assign(params, $auth_params); $this->display(); } public function addclient() { if ($_post && isset($_post[client_id]) && isset($_post[client_secret]) && isset($_post[redirect_uri])) { $this -> oauth -> addclient($_post[client_id], $_post[client_secret], $_post[redirect_uri]); return; } $this->display(); }}
??
这里我们创建了一个私有的oauth对象并在初始化的时候去init它。
?
以上的代码在password那个部分没有做验证,第三种模式需要把thinkoauth类中的checkusercredentials方法进行重写。
?
继续我们写一个受限资源代码。我们这里没有用aop进行拦截,所以我准备直接用一个基类来模拟拦截。
?
?
import(org.oauth.thinkoauth2);class baseaction extends action { protected $oauth = null; function _initialize(){ $this -> oauth = new thinkoauth2(); } public function index(){ if(!$this -> oauth -> verifyaccesstoken()){ $this -> ajaxreturn(null, 'no,no,no', 0, 'json'); exit(); } $this -> ajaxreturn(null, 'oauth-server', 1, 'json'); } }
?
?接下来直接用一个useraction来继承它达到受限的目的,如下:
?
?
class useraction extends baseaction { public function index(){ if(!$this -> oauth -> verifyaccesstoken()){ $this -> ajaxreturn(null, 'no,no,no', 0, 'json'); } $this -> ajaxreturn(null, 'oauth-server', 1, 'json'); } }
??
?
?
最后说明一点,为什么要把user_id耦合进oauth的表呢?因为我们有时候需要从access_token返查user_id,上面的表就能解决这个问题,但其实还有一种方式是在对于access_token生成的时候自动包含user_id再进行加密,在解码的时候从access_token直接取出user_id就可以了。这里关于user_id和密码验证的都没有去实现,需要后期继承thinkoauth2类或者修改checkusercredentials方法才能实现的。?另外这套东西用在rest模式下我认为更好!
其它类似信息

推荐信息