IndexController.calss.php
<?php // +---------------------------------------------------------------------- // | OneThink [ WE CAN DO IT JUST THINK IT ] // +---------------------------------------------------------------------- // | Copyright (c) 2013 http://www.onethink.cn All rights reserved. // +---------------------------------------------------------------------- // | Author: 麥當苗兒 <zuojiazi@vip.qq.com> <http://www.zjzit.cn> // +---------------------------------------------------------------------- namespace Home\Controller; use OT\DataDictionary; use ORG\ThinkSDK\ThinkOauth; /** * 前臺首頁控制器 * 主要獲取首頁聚合資料 */ class IndexController extends HomeController { //系統首頁 public function index(){ $category = D('Category')->getTree(); $lists = D('Document')->lists(null); $this->assign('category',$category);//欄目 $this->assign('lists',$lists);//列表 $this->assign('page',D('Document')->page);//分頁 $this->display('index'); } //登入地址 public function login($type = null){ empty($type) && $this->error('引數錯誤'); //載入ThinkOauth類並例項化一個物件 import("ORG.ThinkSDK.ThinkOauth"); $sns = ThinkOauth::getInstance($type); //跳轉到授權頁面 redirect($sns->getRequestCodeURL()); } //授權回撥地址 public function callback($type = null, $code = null){ (empty($type) || empty($code)) && $this->error('引數錯誤'); //載入ThinkOauth類並例項化一個物件 import("ORG.ThinkSDK.ThinkOauth"); $sns = ThinkOauth::getInstance($type); //騰訊微博需傳遞的額外引數 $extend = null; if($type == 'tencent'){ $extend = array('openid' => $this->_get('openid'), 'openkey' => $this->_get('openkey')); } //請妥善保管這裡獲取到的Token資訊,方便以後API呼叫 //呼叫方法,例項化SDK物件的時候直接作為建構函式的第二個引數傳入 //如: $qq = ThinkOauth::getInstance('qq', $token); $token = $sns->getAccessToken($code , $extend); //獲取當前登入使用者資訊 if(is_array($token)){ $user_info = A('Type', 'Event')->$type($token); echo("<h1>恭喜!使用 {$type} 使用者登入成功</h1><br>"); echo("授權資訊為:<br>"); dump($token); echo("當前登入使用者資訊為:<br>"); dump($user_info); } } }ThinkOauth.Class.php
<?php // +---------------------------------------------------------------------- // | TOPThink [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- // | Copyright (c) 2010 http://topthink.com All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: 麥當苗兒 <zuojiazi.cn@gmail.com> <http://www.zjzit.cn> // +---------------------------------------------------------------------- // | ThinkOauth.class.php 2013-02-25 // +---------------------------------------------------------------------- namespace ORG\ThinkSDK; abstract class ThinkOauth{ /** * oauth版本 * @var string */ protected $Version = '2.0'; /** * 申請應用時分配的app_key * @var string */ protected $AppKey = ''; /** * 申請應用時分配的 app_secret * @var string */ protected $AppSecret = ''; /** * 授權型別 response_type 目前只能為code * @var string */ protected $ResponseType = 'code'; /** * grant_type 目前只能為 authorization_code * @var string */ protected $GrantType = 'authorization_code'; /** * 回撥頁面URL 可以通過配置檔案配置 * @var string */ protected $Callback = ''; /** * 獲取request_code的額外引數 URL查詢字串格式 * @var srting */ protected $Authorize = ''; /** * 獲取request_code請求的URL * @var string */ protected $GetRequestCodeURL = ''; /** * 獲取access_token請求的URL * @var string */ protected $GetAccessTokenURL = ''; /** * API根路徑 * @var string */ protected $ApiBase = ''; /** * 授權後獲取到的TOKEN資訊 * @var array */ protected $Token = null; /** * 呼叫介面型別 * @var string */ private $Type = ''; /** * 構造方法,配置應用資訊 * @param array $token */ public function __construct($token = null){ //設定SDK型別 $class = get_class($this); $this->Type = strtoupper(substr($class, 0, strlen($class)-3)); //獲取應用配置 $config = C("THINK_SDK_{$this->Type}"); if(empty($config['APP_KEY']) || empty($config['APP_SECRET'])){ throw new Exception('請配置您申請的APP_KEY和APP_SECRET'); } else { $this->AppKey = $config['APP_KEY']; $this->AppSecret = $config['APP_SECRET']; $this->Token = $token; //設定獲取到的TOKEN } } /** * 取得Oauth例項 * @static * @return mixed 返回Oauth */ public static function getInstance($type, $token = null) { $name = ucfirst(strtolower($type)) . 'SDK'; require_once "sdk/{$name}.class.php"; if (class_exists($name)) { return new $name($token); } else { E(L('_CLASS_NOT_EXIST_') . ':' . $name); } } /** * 初始化配置 */ private function config(){ $config = C("THINK_SDK_{$this->Type}"); if(!empty($config['AUTHORIZE'])) $this->Authorize = $config['AUTHORIZE']; if(!empty($config['CALLBACK'])) $this->Callback = $config['CALLBACK']; else throw new Exception('請配置回撥頁面地址'); } /** * 請求code */ public function getRequestCodeURL(){ $this->config(); //Oauth 標準引數 $params = array( 'client_id' => $this->AppKey, 'redirect_uri' => $this->Callback, 'response_type' => $this->ResponseType, ); //獲取額外引數 if($this->Authorize){ parse_str($this->Authorize, $_param); if(is_array($_param)){ $params = array_merge($params, $_param); } else { throw new Exception('AUTHORIZE配置不正確!'); } } return $this->GetRequestCodeURL . '?' . http_build_query($params); } /** * 獲取access_token * @param string $code 上一步請求到的code */ public function getAccessToken($code, $extend = null){ $this->config(); $params = array( 'client_id' => $this->AppKey, 'client_secret' => $this->AppSecret, 'grant_type' => $this->GrantType, 'code' => $code, 'redirect_uri' => $this->Callback, ); $data = $this->http($this->GetAccessTokenURL, $params, 'POST'); $this->Token = $this->parseToken($data, $extend); return $this->Token; } /** * 合併預設引數和額外引數 * @param array $params 預設引數 * @param array/string $param 額外引數 * @return array: */ protected function param($params, $param){ if(is_string($param)) parse_str($param, $param); return array_merge($params, $param); } /** * 獲取指定API請求的URL * @param string $api API名稱 * @param string $fix api字尾 * @return string 請求的完整URL */ protected function url($api, $fix = ''){ return $this->ApiBase . $api . $fix; } /** * 傳送HTTP請求方法,目前只支援CURL傳送請求 * @param string $url 請求URL * @param array $params 請求引數 * @param string $method 請求方法GET/POST * @return array $data 響應資料 */ protected function http($url, $params, $method = 'GET', $header = array(), $multi = false){ $opts = array( CURLOPT_TIMEOUT => 30, CURLOPT_RETURNTRANSFER => 1, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_HTTPHEADER => $header ); /* 根據請求型別設定特定引數 */ switch(strtoupper($method)){ case 'GET': $opts[CURLOPT_URL] = $url . '?' . http_build_query($params); break; case 'POST': //判斷是否傳輸檔案 $params = $multi ? $params : http_build_query($params); $opts[CURLOPT_URL] = $url; $opts[CURLOPT_POST] = 1; $opts[CURLOPT_POSTFIELDS] = $params; break; default: throw new Exception('不支援的請求方式!'); } /* 初始化並執行curl請求 */ $ch = curl_init(); curl_setopt_array($ch, $opts); $data = curl_exec($ch); $error = curl_error($ch); curl_close($ch); if($error) throw new Exception('請求發生錯誤:' . $error); return $data; } /** * 抽象方法,在SNSSDK中實現 * 組裝介面呼叫引數 並呼叫介面 */ abstract protected function call($api, $param = '', $method = 'GET', $multi = false); /** * 抽象方法,在SNSSDK中實現 * 解析access_token方法請求後的返回值 */ abstract protected function parseToken($result, $extend); /** * 抽象方法,在SNSSDK中實現 * 獲取當前授權使用者的SNS標識 */ abstract public function openid(); }GoogleSDK.class.php
<?php // +---------------------------------------------------------------------- // | TOPThink [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- // | Copyright (c) 2010 http://topthink.com All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: 麥當苗兒 <zuojiazi.cn@gmail.com> <http://www.zjzit.cn> // +---------------------------------------------------------------------- // | GoogleSDK.class.php 2013-02-26 // +---------------------------------------------------------------------- namespace ORG\ThinkSDK\sdk; use ORG\ThinkSDK\ThinkOauth; class GoogleSDK extends ThinkOauth{ /** * 獲取requestCode的api介面 * @var string */ protected $GetRequestCodeURL = 'https://accounts.google.com/o/oauth2/auth'; /** * 獲取access_token的api介面 * @var string */ protected $GetAccessTokenURL = 'https://accounts.google.com/o/oauth2/token'; /** * 獲取request_code的額外引數 URL查詢字串格式 * @var srting */ protected $Authorize = 'scope=https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email'; /** * API根路徑 * @var string */ protected $ApiBase = 'https://www.googleapis.com/oauth2/v1/'; /** * 組裝介面呼叫引數 並呼叫介面 * @param string $api 微博API * @param string $param 呼叫API的額外引數 * @param string $method HTTP請求方法 預設為GET * @return json */ public function call($api, $param = '', $method = 'GET', $multi = false){ /* Google 呼叫公共引數 */ $params = array(); $header = array("Authorization: Bearer {$this->Token['access_token']}"); $data = $this->http($this->url($api), $this->param($params, $param), $method, $header); return json_decode($data, true); } /** * 解析access_token方法請求後的返回值 * @param string $result 獲取access_token的方法的返回值 */ protected function parseToken($result, $extend){ $data = json_decode($result, true); if($data['access_token'] && $data['token_type'] && $data['expires_in']){ $this->Token = $data; $data['openid'] = $this->openid(); return $data; } else throw new Exception("獲取 Google ACCESS_TOKEN出錯:未知錯誤"); } /** * 獲取當前授權應用的openid * @return string */ public function openid(){ if(isset($this->Token['openid'])) return $this->Token['openid']; $data = $this->call('userinfo'); if(!empty($data['id'])) return $data['id']; else throw new Exception('沒有獲取到 Google 使用者ID!'); } }