适用于kohana3.x
1. [文件]
oauth.zip oauth.zip
2. [文件]
oauth.php class controller_oauth extends controller {
public function action_index() {
$result = array('status' => '400');
$this->sendquery($result);
}
// 获取未授权的request token
public function action_request() {
$result = array('status' => '400');
$provider = new oauth_provider();
$provider->setrequesttokenquery();
try {
$provider->checkrequest();
$token = $provider->generaterequesttoken();
$result['status'] = 200;
$result = arr::merge($result, $token);
} catch (exception $e) {
$result['code'] = $e->getcode();
$result['message'] = $e->getmessage();
}
$this->sendquery($result);
}
// 获取用户授权的request token
public function action_authorize() {
$result = array('status' => '400');
try {
$oauth_token = arr::get($_request, 'oauth_token');
if (!$oauth_token) {
throw new exception('缺少 oauth_token');
}
$request_token = oauth_token::findbytoken($oauth_token);
if(!is_object($request_token) || !$request_token->isrequest()){
throw new exception('oauth_token 错误');
}
$username = arr::get($_request, 'username');
$password = arr::get($_request, 'password');
if (auth::instance()->login($username, $password) !== true) {
throw new exception('用户名或密码错误');
}
$request_token->setverifier(oauth_provider::generateverifier());
$request_token->setuserid(auth::instance()->instance()->get_user()->id);
$result['status'] = 200;
$result['message'] = '授权成功';
$result['callback'] = $request_token->getcallback();
$result['oauth_token'] = $oauth_token;
$result['oauth_verifier'] = $request_token->getverifier();
} catch (exception $e) {
$result['message'] = $e->getmessage();
}
$this->sendquery($result);
}
// 使用授权后的request token换取access toke
public function action_access() {
$result = array('status' => '400');
// xauth
$x_auth_mode = arr::get($_request, 'x_auth_mode');
if ($x_auth_mode == 'client_auth') {
$username = arr::get($_request, 'x_auth_username');
$password = arr::get($_request, 'x_auth_password');
if (auth::instance()->login($username, $password) !== true) {
throw new exception('用户名或密码错误');
}
$userid = auth::instance()->instance()->get_user()->id;
try {
// 生成request token
$provider = new oauth_provider();
$provider->setrequesttokenquery();
$provider->checkrequest();
$consumer = $provider->getconsumer();
if ($consumer->gettype() !== 1) {
throw new exception('请申请xauth认证');
}
$token = sha1(oauthprovider::generatetoken(20, true));
$secret = sha1(oauthprovider::generatetoken(20, true));
$oauth_token = orm::factory('oauth_token');
$oauth_token->type = 2;
$oauth_token->consumer_id = $consumer->getid();
$oauth_token->token = $token;
$oauth_token->token_secret = $secret;
$oauth_token->callback_url = '';
$oauth_token->user_id = $userid;
$oauth_token->verifier = '';
$oauth_token->save();
$result = array('status' => 200, 'oauth_token' => $token, 'oauth_token_secret' => $secret);
} catch (exception $e) {
$result['code'] = $e->getcode();
$result['message'] = $e->getmessage();
}
$this->sendquery($result);
} else {
$provider = new oauth_provider();
try {
$provider->checkrequest();
$token = $provider->generateaccesstoken();
$result['status'] = 200;
$result = arr::merge($result, $token);
} catch (exception $e) {
$result['code'] = $e->getcode();
$result['message'] = $e->getmessage();
}
$this->sendquery($result);
}
}
public function action_test() {
$result = array('status' => '400');
$provider = new oauth_provider();
try {
$provider->checkrequest();
$userid = $provider->getuserid();
$result['status'] = 200;
$result['message'] = '';
$result['userid'] = $userid;
} catch (exception $e) {
$result['message'] = $e->getmessage();
}
$this->sendquery($result);
}
// 输出json
public function sendquery($result, $header = true) {
$body = is_array($result) ? http_build_query($result) : $result;
$this->sendbody($body);
}
// 输出
public function sendbody($body) {
$this->response->body($body);
echo $this->response->send_headers()->body();
exit;
}
}
3. [文件]
provider.php<?php defined('syspath') or die('no direct script access.');
/**
* @author zhuzongxin dreamsxin@qq.com
*/
class oauth_provider {
private $oauth;
private $consumer;
private $user_id;
private $authentification_url;
public static function createconsumer() {
$key = sha1(oauthprovider::generatetoken(20, true));
$secret = sha1(oauthprovider::generatetoken(20, true));
return oauth_consumer::create($key, $secret);
}
public function __construct() {
$config = kohana::$config->load('oauth');
$this->authentification_url = url::base(true).arr::get($config, 'authentification_url');
/* create our instance */
$this->oauth = new oauthprovider();
/* setup check functions */
$this->oauth->consumerhandler(array($this, 'checkconsumer'));
$this->oauth->timestampnoncehandler(array($this, 'checknonce'));
$this->oauth->tokenhandler(array($this, 'checktoken'));
}
public function checkrequest() {
$this->oauth->checkoauthrequest();
}
public function setrequesttokenquery() {
$this->oauth->isrequesttokenendpoint(true);
//$this->oauth->addrequiredparameter("oauth_callback");
}
public function generaterequesttoken() {
$token = sha1(oauthprovider::generatetoken(20, true));
$token_secret = sha1(oauthprovider::generatetoken(20, true));
$callback = $this->oauth->callback;
oauth_token::createrequesttoken($this->consumer, $token, $token_secret, $callback);
return array('authentification_url' => $this->authentification_url, 'oauth_token' => $token, 'oauth_token_secret' => $token_secret, 'oauth_callback_confirmed' => 'true');
}
public function generateaccesstoken() {
$access_token = sha1(oauthprovider::generatetoken(20, true));
$secret = sha1(oauthprovider::generatetoken(20, true));
$token = oauth_token::findbytoken($this->oauth->token);
$token->changetoaccesstoken($access_token, $secret);
return array('oauth_token' => $access_token, 'oauth_token_secret' => $secret);
}
public static function generateverifier() {
$verifier = sha1(oauthprovider::generatetoken(20, true));
return $verifier;
}
public function checkconsumer($provider) {
$return = oauth_consumer_key_unknown;
$aconsumer = oauth_consumer::findbykey($provider->consumer_key);
if (is_object($aconsumer)) {
if (!$aconsumer->isactive()) {
$return = oauth_consumer_key_refused;
} else {
$this->consumer = $aconsumer;
$provider->consumer_secret = $this->consumer->getsecretkey();
$return = oauth_ok;
}
}
return $return;
}
public function checktoken($provider) {
$token = oauth_token::findbytoken($provider->token);
if (is_null($token)) {
return oauth_token_rejected;
} elseif ($token->gettype() == 1) {
if ($token->getverifier() != $provider->verifier) {
return oauth_verifier_invalid;
} else {
$provider->token_secret = $token->getsecret();
return oauth_ok;
}
} elseif ($token->gettype() == 2) {
if ($token->getexpires() > 0 && time() - strtotime($token->getcreated()) > (int)$token->getexpires()) {
return oauth_token_expired;
}
$this->user_id = $token->getuserid();
$provider->token_secret = $token->getsecret();
return oauth_ok;
}
}
public function checknonce($provider) {
if ($this->oauth->timestamp < time() - 5 * 60) {
return oauth_bad_timestamp;
} elseif ($this->consumer->hasnonce($provider->nonce, $this->oauth->timestamp)) {
return oauth_bad_nonce;
} else {
$this->consumer->addnonce($this->oauth->nonce);
return oauth_ok;
}
}
public function getuserid() {
if ($this->user_id) {
return $this->user_id;
} else {
throw new exception("user not authentificated");
}
}
public function getconsumer() {
return $this->consumer;
}
}
