PageRenderTime 60ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Addons/SyncLogin/ThinkSDK/ThinkOauth.class.php

https://gitlab.com/xuebutayan/yshop
PHP | 274 lines | 116 code | 34 blank | 124 comment | 12 complexity | 9e63038fd940cefee675c7f075d70cca MD5 | raw file
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | TOPThink [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2010 http://topthink.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: 麦当苗儿 <zuojiazi.cn@gmail.com> <http://www.zjzit.cn>
  10. // +----------------------------------------------------------------------
  11. // | ThinkOauth.class.php 2013-02-25
  12. // +----------------------------------------------------------------------
  13. abstract class ThinkOauth{
  14. /**
  15. * oauth版本
  16. * @var string
  17. */
  18. protected $Version = '2.0';
  19. /**
  20. * 申请应用时分配的app_key
  21. * @var string
  22. */
  23. protected $AppKey = '';
  24. /**
  25. * 申请应用时分配的 app_secret
  26. * @var string
  27. */
  28. protected $AppSecret = '';
  29. /**
  30. * 授权类型 response_type 目前只能为code
  31. * @var string
  32. */
  33. protected $ResponseType = 'code';
  34. /**
  35. * grant_type 目前只能为 authorization_code
  36. * @var string
  37. */
  38. protected $GrantType = 'authorization_code';
  39. /**
  40. * 回调页面URL 可以通过配置文件配置
  41. * @var string
  42. */
  43. protected $Callback = '';
  44. /**
  45. * 获取request_code的额外参数 URL查询字符串格式
  46. * @var srting
  47. */
  48. protected $Authorize = '';
  49. /**
  50. * 获取request_code请求的URL
  51. * @var string
  52. */
  53. protected $GetRequestCodeURL = '';
  54. /**
  55. * 获取access_token请求的URL
  56. * @var string
  57. */
  58. protected $GetAccessTokenURL = '';
  59. /**
  60. * API根路径
  61. * @var string
  62. */
  63. protected $ApiBase = '';
  64. /**
  65. * 授权后获取到的TOKEN信息
  66. * @var array
  67. */
  68. protected $Token = null;
  69. /**
  70. * 调用接口类型
  71. * @var string
  72. */
  73. private $Type = '';
  74. /**
  75. * 构造方法,配置应用信息
  76. * @param array $token
  77. */
  78. public function __construct($token = null){
  79. //设置SDK类型
  80. $class = get_class($this);
  81. $this->Type = strtoupper(substr($class, 0, strlen($class)-3));
  82. //获取应用配置
  83. /* $config = C("THINK_SDK_{$this->Type}");*/
  84. $config = D('addons')->where(array('name'=>'SyncLogin'))->find();
  85. $config = json_decode($config['config'], true);
  86. $type = substr($class, 0, strlen($class)-3);
  87. if(empty($config[$type.'KEY']) || empty($config[$type.'Secret'])){
  88. throw new Exception('请配置您申请的APP_KEY和APP_SECRET');
  89. } else {
  90. $this->AppKey = $config[$type.'KEY'];
  91. $this->AppSecret = $config[$type.'Secret'];
  92. $this->Token = $token; //设置获取到的TOKEN
  93. }
  94. }
  95. /**
  96. * 取得Oauth实例
  97. * @static
  98. * @return mixed 返回Oauth
  99. */
  100. public static function getInstance($type, $token = null) {
  101. $name = ucfirst(strtolower($type)) . 'SDK';
  102. require_once "sdk/{$name}.class.php";
  103. if (class_exists($name)) {
  104. return new $name($token);
  105. } else {
  106. halt(L('_CLASS_NOT_EXIST_') . ':' . $name);
  107. }
  108. }
  109. /**
  110. * 初始化配置
  111. */
  112. private function config(){
  113. if(C('URL_MODEL') == 2){
  114. $this->Callback = "http://".$_SERVER ['HTTP_HOST'].'/index.php?s='.addons_url('SyncLogin://Base/callback',array('type'=>strtolower($this->Type)));
  115. }
  116. else{
  117. $this->Callback = "http://".$_SERVER['HTTP_HOST'].addons_url('SyncLogin://Base/callback',array('type'=>strtolower($this->Type)));
  118. }
  119. /* $config = C("THINK_SDK_{$this->Type}");
  120. if(!empty($config['AUTHORIZE']))
  121. $this->Authorize = $config['AUTHORIZE'];
  122. if(!empty($config['CALLBACK']))
  123. $this->Callback = $config['CALLBACK'];
  124. else
  125. throw new Exception('请配置回调页面地址');*/
  126. }
  127. /**
  128. * 请求code
  129. */
  130. public function getRequestCodeURL(){
  131. $this->config();
  132. //Oauth 标准参数
  133. $params = array(
  134. 'client_id' => $this->AppKey,
  135. 'redirect_uri' => $this->Callback,
  136. 'response_type' => $this->ResponseType,
  137. );
  138. //获取额外参数
  139. if($this->Authorize){
  140. parse_str($this->Authorize, $_param);
  141. if(is_array($_param)){
  142. $params = array_merge($params, $_param);
  143. } else {
  144. throw new Exception('AUTHORIZE配置不正确!');
  145. }
  146. }
  147. return $this->GetRequestCodeURL . '?' . http_build_query($params);
  148. }
  149. /**
  150. * 获取access_token
  151. * @param string $code 上一步请求到的code
  152. */
  153. public function getAccessToken($code, $extend = null){
  154. $this->config();
  155. $params = array(
  156. 'client_id' => $this->AppKey,
  157. 'client_secret' => $this->AppSecret,
  158. 'grant_type' => $this->GrantType,
  159. 'code' => $code,
  160. 'redirect_uri' => $this->Callback,
  161. );
  162. $data = $this->http($this->GetAccessTokenURL, $params, 'POST');
  163. $this->Token = $this->parseToken($data, $extend);
  164. return $this->Token;
  165. }
  166. /**
  167. * 合并默认参数和额外参数
  168. * @param array $params 默认参数
  169. * @param array/string $param 额外参数
  170. * @return array:
  171. */
  172. protected function param($params, $param){
  173. if(is_string($param))
  174. parse_str($param, $param);
  175. return array_merge($params, $param);
  176. }
  177. /**
  178. * 获取指定API请求的URL
  179. * @param string $api API名称
  180. * @param string $fix api后缀
  181. * @return string 请求的完整URL
  182. */
  183. protected function url($api, $fix = ''){
  184. return $this->ApiBase . $api . $fix;
  185. }
  186. /**
  187. * 发送HTTP请求方法,目前只支持CURL发送请求
  188. * @param string $url 请求URL
  189. * @param array $params 请求参数
  190. * @param string $method 请求方法GET/POST
  191. * @return array $data 响应数据
  192. */
  193. protected function http($url, $params, $method = 'GET', $header = array(), $multi = false){
  194. $opts = array(
  195. CURLOPT_TIMEOUT => 30,
  196. CURLOPT_RETURNTRANSFER => 1,
  197. CURLOPT_SSL_VERIFYPEER => false,
  198. CURLOPT_SSL_VERIFYHOST => false,
  199. CURLOPT_HTTPHEADER => $header
  200. );
  201. /* 根据请求类型设置特定参数 */
  202. switch(strtoupper($method)){
  203. case 'GET':
  204. $opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
  205. break;
  206. case 'POST':
  207. //判断是否传输文件
  208. $params = $multi ? $params : http_build_query($params);
  209. $opts[CURLOPT_URL] = $url;
  210. $opts[CURLOPT_POST] = 1;
  211. $opts[CURLOPT_POSTFIELDS] = $params;
  212. break;
  213. default:
  214. throw new Exception('不支持的请求方式!');
  215. }
  216. /* 初始化并执行curl请求 */
  217. $ch = curl_init();
  218. curl_setopt_array($ch, $opts);
  219. $data = curl_exec($ch);
  220. $error = curl_error($ch);
  221. curl_close($ch);
  222. if($error) throw new Exception('请求发生错误:' . $error);
  223. return $data;
  224. }
  225. /**
  226. * 抽象方法,在SNSSDK中实现
  227. * 组装接口调用参数 并调用接口
  228. */
  229. abstract protected function call($api, $param = '', $method = 'GET', $multi = false);
  230. /**
  231. * 抽象方法,在SNSSDK中实现
  232. * 解析access_token方法请求后的返回值
  233. */
  234. abstract protected function parseToken($result, $extend);
  235. /**
  236. * 抽象方法,在SNSSDK中实现
  237. * 获取当前授权用户的SNS标识
  238. */
  239. abstract public function openid();
  240. }