1. 程式人生 > >【PHP】基於ThinkPHP框架搭建OAuth2.0服務

【PHP】基於ThinkPHP框架搭建OAuth2.0服務

這幾天一直在搞OAuth2.0的東西,寫SDK啥的,為了更加深入的瞭解服務端的OAuth驗證機制,就自己動手搭了個php下OAuth的環境,並且將它移植到了自己比較熟的tp框架裡。

廢話不少說,開動。

其實網上是有OAuth2.0的php版本的。

好,這裡我們可以把下載下來的包解壓,把Lib下的OAuth.inc改名為OAuth2.class.php後放到tp核心包下的目錄下:

Tree程式碼  收藏程式碼
  1. /Extend/Library/ORG/OAuth/OAuth2.class.php  

接下來我們要繼承這個類;

在這個目錄下新建一個ThinkOAuth2.class.php檔案:

Php程式碼  收藏程式碼
  1. <?php  
  2. /** 
  3.  * @category ORG 
  4.  * @package ORG 
  5.  * @author Leyteris 
  6.  * @version 2012.3.16 
  7.  */  
  8. // OAUTH2_DB_DSN  資料庫連線DSN  
  9. // OAUTH2_CODES_TABLE 伺服器表名稱  
  10. // OAUTH2_CLIENTS_TABLE 客戶端表名稱  
  11. // OAUTH2_TOKEN_TABLE 驗證碼錶名稱  
  12. import("ORG.OAuth.OAuth2");  
  13. class ThinkOAuth2 extends OAuth2 {  
  14.     private
     $db;  
  15.     private $table;  
  16.     /** 
  17.      * 構造 
  18.      */  
  19.     public function __construct() {  
  20.         parent::__construct();  
  21.         $this -> db = Db::getInstance(C('OAUTH2_DB_DSN'));  
  22.         $this -> table = array(  
  23.             'auth_codes'=>C('OAUTH2_CODES_TABLE'),  
  24.             'clients'
    =>C('OAUTH2_CLIENTS_TABLE'),  
  25.             'tokens'=>C('OAUTH2_TOKEN_TABLE')  
  26.         );  
  27.     }  
  28.     /** 
  29.      * 析構 
  30.      */  
  31.     function __destruct() {  
  32.         $this->db = NULL; // Release db connection  
  33.     }  
  34.     private function handleException($e) {  
  35.         echo "Database error: " . $e->getMessage();  
  36.         exit;  
  37.     }  
  38.     /** 
  39.      *  
  40.      * 增加client 
  41.      * @param string $client_id 
  42.      * @param string $client_secret 
  43.      * @param string $redirect_uri 
  44.      */  
  45.     public function addClient($client_id$client_secret$redirect_uri) {  
  46.         $time = time();  
  47.         $sql = "INSERT INTO {$this -> table['clients']} ".  
  48.             "(client_id, client_secret, redirect_uri, create_time) VALUES (\"{$client_id}\", \"{$client_secret}\", \"{$redirect_uri}\",\"{$time}\")";  
  49.         $this -> db -> execute($sql);  
  50.     }  
  51.     /** 
  52.      * Implements OAuth2::checkClientCredentials() 
  53.      * @see OAuth2::checkClientCredentials() 
  54.      */  
  55.     protected function checkClientCredentials($client_id$client_secret = NULL) {  
  56.         $sql = "SELECT client_secret FROM {$this -> table['clients']} ".  
  57.             "WHERE client_id = \"{$client_id}\"";  
  58.         $result = $this -> db -> query($sql);  
  59.         if ($client_secret === NULL) {  
  60.             return $result !== FALSE;  
  61.         }  
  62.         //Log::write("checkClientCredentials : ".$result);  
  63.         //Log::write("checkClientCredentials : ".$result[0]);  
  64.         //Log::write("checkClientCredentials : ".$result[0]["client_secret"]);  
  65.         return $result[0]["client_secret"] == $client_secret;  
  66.     }  
  67.     /** 
  68.      * Implements OAuth2::getRedirectUri(). 
  69.      * @see OAuth2::getRedirectUri() 
  70.      */  
  71.     protected function getRedirectUri($client_id) {  
  72.         $sql = "SELECT redirect_uri FROM {$this -> table['clients']} ".  
  73.             "WHERE client_id = \"{$client_id}\"";  
  74.         $result = $this -> db -> query($sql);  
  75.         if ($result === FALSE) {  
  76.             return FALSE;  
  77.         }  
  78.         //Log::write("getRedirectUri : ".$result);  
  79.         //Log::write("getRedirectUri : ".$result[0]);  
  80.         //Log::write("getRedirectUri : ".$result[0]["redirect_uri"]);  
  81.         return isset($result[0]["redirect_uri"]) && $result[0]["redirect_uri"] ? $result[0]["redirect_uri"] : NULL;  
  82.     }  
  83.     /** 
  84.      * Implements OAuth2::getAccessToken(). 
  85.      * @see OAuth2::getAccessToken() 
  86.      */  
  87.     protected function getAccessToken($access_token) {  
  88.         $sql = "SELECT client_id, expires, scope FROM {$this -> table['tokens']} ".  
  89.             "WHERE access_token = \"{$access_token}\"";  
  90.         $result = $this -> db -> query($sql);  
  91.         //Log::write("getAccessToken : ".$result);  
  92.         //Log::write("getAccessToken : ".$result[0]);  
  93.         return $result !== FALSE ? $result : NULL;  
  94.     }  
  95.     /** 
  96.      * Implements OAuth2::setAccessToken(). 
  97.      * @see OAuth2::setAccessToken() 
  98.      */  
  99.     protected function setAccessToken($access_token$client_id$expires$scope = NULL) {  
  100.         $sql = "INSERT INTO {$this -> table['tokens']} ".  
  101.             "(access_token, client_id, expires, scope) ".  
  102.             "VALUES (\"{$access_token}\", \"{$client_id}\", \"{$expires}\", \"{$scope}\")";  
  103.         $this -> db -> execute($sql);  
  104.     }  
  105.     /** 
  106.      * Overrides OAuth2::getSupportedGrantTypes(). 
  107.      * @see OAuth2::getSupportedGrantTypes() 
  108.      */  
  109.     protected function getSupportedGrantTypes() {  
  110.         return array(  
  111.             OAUTH2_GRANT_TYPE_AUTH_CODE  
  112.         );  
  113.     }  
  114.     /** 
  115.      * Overrides OAuth2::getAuthCode(). 
  116.      * @see OAuth2::getAuthCode() 
  117.      */  
  118.     protected function getAuthCode($code) {  
  119.         $sql = "SELECT code, client_id, redirect_uri, expires, scope ".  
  120.             "FROM {$this -> table['auth_codes']} WHERE code = \"{$code}\"";  
  121.         $result = $this -> db -> query($sql);  
  122.         //Log::write("getAuthcode : ".$result);  
  123.         //Log::write("getAuthcode : ".$result[0]);  
  124.         //Log::write("getAuthcode : ".$result[0]["code"]);  
  125.         return $result !== FALSE ? $result[0] : NULL;  
  126.     }  
  127.     /** 
  128.      * Overrides OAuth2::setAuthCode(). 
  129.      * @see OAuth2::setAuthCode() 
  130.      */  
  131.     protected function setAuthCode($code$client_id$redirect_uri$expires$scope = NULL) {  
  132.         $time = time();  
  133.         $sql = "INSERT INTO {$this -> table['auth_codes']} ".  
  134.             "(code, client_id, redirect_uri, expires, scope) ".  
  135.             "VALUES (\"${code}\", \"${client_id}\", \"${redirect_uri}\", \"${expires}\", \"${scope}\")";  
  136.         $result = $this -> db -> execute($sql);  
  137.   }  
  138.   /** 
  139.    * Overrides OAuth2::checkUserCredentials(). 
  140.    * @see OAuth2::checkUserCredentials() 
  141.    */  
  142.   protected function checkUserCredentials($client_id$username$password){  
  143.     return TRUE;  
  144.   }  
  145. }  

 在這裡我們需要建立資料庫:

Sql程式碼  收藏程式碼
  1. CREATE TABLE `oauth_client` (  
  2.   `id` bigint(20) NOT NULL auto_increment,  
  3.   `client_id` varchar(32) NOT NULL,  
  4.   `client_secret` varchar(32) NOT NULL,  
  5.   `redirect_uri` varchar(200) NOT NULL,  
  6.   `create_time` int(20) default NULL,  
  7.   PRIMARY KEY  (`id`)  
  8. ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;  
  9. CREATE TABLE `oauth_code` (  
  10.   `id` bigint(20) NOT NULL auto_increment,  
  11.   `client_id` varchar(32) NOT NULL,  
  12.   `user_id` varchar(32) NOT NULL,  
  13.   `code` varchar(40) NOT NULL,  
  14.   `redirect_uri` varchar(200) NOT NULL,  
  15.   `expires` int(11) NOT NULL,  
  16.   `scope` varchar(250) default NULL,  
  17.   PRIMARY KEY  (`id`)  
  18. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;  
  19. CREATE TABLE `oauth_token` (  
  20.   `id` bigint(20) NOT NULL auto_increment,  
  21.   `client_id` varchar(32) NOT NULL,  
  22.   `user_id` varchar(32) NOT NULL,  
  23.   `access_token` varchar(40) NOT NULL,  
  24.   `refresh_token` varchar(40) NOT NULL,  
  25.   `expires` int(11) NOT NULL,  
  26.   `scope` varchar(200) default NULL,  
  27.   PRIMARY KEY  (`id`)  
  28. ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;  

上面的資料庫表名可以自己隨便定;但是要在config.php配置表名:

Php程式碼  收藏程式碼
  1. 'OAUTH2_CODES_TABLE'=>'oauth_code',  
  2. 'OAUTH2_CLIENTS_TABLE'=>'oauth_client',  
  3. 'OAUTH2_TOKEN_TABLE'=>'oauth_token',  

如果OAuth的伺服器不是當前伺服器,那就要指定下DSN地址了:

Php程式碼  收藏程式碼
  1. 'OAUTH2_DB_DSN'=>'mysql://root:[email protected]:3306/database'  

好了,大致的核心庫程式碼就