Maison > développement back-end > tutoriel php > 基于ThinkPHP框架筹建OAuth2.0服务

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

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
Libérer: 2016-06-13 10:29:49
original
994 Les gens l'ont consulté

基于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核心包下的目录下:

?

1

/Extend/Library/ORG/OAuth/OAuth2.class.php

Copier après la connexion

?

接下来我们要继承这个类;

在这个目录下新建一个ThinkOAuth2.class.php文件:

?

1

<?php/** * @category ORG * @package ORG * @author Leyteris * @version 2012.3.16 */// OAUTH2_DB_DSN  数据库连接DSN// OAUTH2_CODES_TABLE 服务器表名称// OAUTH2_CLIENTS_TABLE 客户端表名称// OAUTH2_TOKEN_TABLE 验证码表名称import("ORG.OAuth.OAuth2");class ThinkOAuth2 extends OAuth2 {  private $db;    private $table; /**  * 构造    */ public function __construct() {     parent::__construct();      $this -> 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;  }}

Copier après la connexion

?

?在这里我们需要创建数据库:

?

1

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;

Copier après la connexion
?

?

上面的数据库表名可以自己随便定;但是要在config.php配置表名:

?

1

'OAUTH2_CODES_TABLE'=>'oauth_code','OAUTH2_CLIENTS_TABLE'=>'oauth_client','OAUTH2_TOKEN_TABLE'=>'oauth_token',

Copier après la connexion

?

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

?

?

1

'OAUTH2_DB_DSN'=>'mysql://root:[email&#160;protected]:3306/database'

Copier après la connexion

?

?

好了,大致的核心库代码就是如此。接下来要使用它

?

我们创建一个OAuth的Action负责OAuth2的一些验证(OauthAction.class.php)

?

1

import("ORG.OAuth.ThinkOAuth2");class OauthAction extends Action {      private $oauth = NULL;  function _initialize(){             header("Content-Type: application/json");       <span style="white-space: pre;">  </span>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();    }}

Copier après la connexion
?

?

这里我们创建了一个私有的oauth对象并在初始化的时候去init它。

?

以上的代码在password那个部分没有做验证,第三种模式需要把ThinkOAuth类中的checkUserCredentials方法进行重写。

?

继续我们写一个受限资源代码。我们这里没有用AOP进行拦截,所以我准备直接用一个基类来模拟拦截。

?

?

1

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');            }    }

Copier après la connexion

?

?接下来直接用一个UserAction来继承它达到受限的目的,如下:

?

?

1

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');            }    }

Copier après la connexion
?

?

?

?

最后说明一点,为什么要把user_id耦合进OAuth的表呢?因为我们有时候需要从access_token返查user_id,上面的表就能解决这个问题,但其实还有一种方式是在对于access_token生成的时候自动包含user_id再进行加密,在解码的时候从access_token直接取出user_id就可以了。这里关于user_id和密码验证的都没有去实现,需要后期继承ThinkOAuth2类或者修改checkUserCredentials方法才能实现的。?另外这套东西用在REST模式下我认为更好!

Étiquettes associées:
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal