PHP写的oauth认证服务端
程序员文章站
2022-05-26 10:07:26
...
适用于Kohana3.x
1. [文件] 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; } }
上一篇: phpunit 的大局安装