日期:2014-05-17  浏览次数:20716 次

基于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文件:

?

<?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}\")";
		
		$t