ホームページ  >  記事  >  バックエンド開発  >  ThinkPHP フレームワークに基づいた OAuth2.0 サービスの構築の準備

ThinkPHP フレームワークに基づいた OAuth2.0 サービスの構築の準備

WBOY
WBOYオリジナル
2016-06-13 13:24:531131ブラウズ

ThinkPHP フレームワークに基づいて OAuth2.0 サービスを構築します

最近、OAuth2.0 の開発に取り組んでおり、SDK を書いたりしています。サーバー側の OAuth 検証メカニズムをより深く理解するために、以下に OAuth 環境を構築しました。私自身も PHP を使用しており、それを使い慣れた 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 ファイルを作成します:

?

<?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;
  }
}

?

? ここでデータベースを作成する必要があります:

?

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'
?

?

さて、これが大まかなコア ライブラリ コードです。次に使用します

?

OAuth2 の一部の検証を担当する OAuth アクション (OauthAction.class.php) を作成します

?

?
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();
	}
}
?

ここではプライベート oauth オブジェクトを作成し、初期化中にそれを初期化します。

?

上記のコードはパスワード部分を検証しません。3 番目のモードでは、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 モードで使用するとより良いと思います。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。