OAuth.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <?php
  2. /**
  3. * OAuth.php UTF-8
  4. *
  5. *
  6. * @date : 2018/4/25 15:17
  7. *
  8. * @license 这不是一个自由软件,未经授权不许任何使用和传播。
  9. * @author : wuyonghong <wyh@huosdk.com>
  10. * @version : HUOSDK 8.0
  11. */
  12. namespace huolib\oauth;
  13. use think\Exception;
  14. use think\Session;
  15. abstract class OAuth {
  16. /**
  17. * oauth版本
  18. *
  19. * @var string
  20. */
  21. protected $version = '2.0';
  22. /**
  23. * 申请应用时分配的app_key
  24. *
  25. * @var string
  26. */
  27. protected $app_key = '';
  28. /**
  29. * 申请应用时分配的 app_secret
  30. *
  31. * @var string
  32. */
  33. protected $app_secret = '';
  34. /**
  35. * 授权类型 response_type 目前只能为code
  36. *
  37. * @var string
  38. */
  39. protected $response_type = 'code';
  40. /**
  41. * grant_type 目前只能为 authorization_code
  42. *
  43. * @var string
  44. */
  45. protected $grant_type = 'authorization_code';
  46. /**
  47. * 回调页面URL 可以通过配置文件配置
  48. *
  49. * @var string
  50. */
  51. protected $callback = '';
  52. /**
  53. * 获取request_code的额外参数 URL查询字符串格式
  54. *
  55. * @var string
  56. */
  57. protected $authorize = '';
  58. /**
  59. * 获取request_code请求的URL
  60. *
  61. * @var string
  62. */
  63. protected $request_code_url = '';
  64. /**
  65. * 获取access_token请求的URL
  66. *
  67. * @var string
  68. */
  69. protected $access_token_url = '';
  70. /**
  71. * 更新Access token的api接口
  72. *
  73. * @var String
  74. */
  75. protected $refresh_token_url = '';
  76. /**
  77. * API根路径
  78. *
  79. * @var string
  80. */
  81. protected $api_base = '';
  82. /**
  83. * 授权后获取到的token信息
  84. *
  85. * @var array
  86. */
  87. protected $token = ['openid' => '', 'access_token' => '', 'expires_in' => 0];
  88. /**
  89. * 调用接口类型
  90. *
  91. * @var string
  92. */
  93. private $type = '';
  94. protected $state = '';
  95. /**
  96. * 构造方法,配置应用信息
  97. *
  98. * @param array $config
  99. * @param array $token
  100. *
  101. * @throws Exception
  102. */
  103. public function __construct($config = [], $token = null) {
  104. //设置SDK类型
  105. $class = get_class($this);
  106. $this->type = strtoupper(substr($class, 0, strlen($class) - 3));
  107. //获取应用配置
  108. if (empty($config['APP_KEY']) || empty($config['APP_SECRET'])) {
  109. throw new Exception('请配置您申请的APP_KEY和APP_SECRET');
  110. } else {
  111. $this->app_key = $config['APP_KEY'];
  112. if (!empty($token['oauth_app_key'])) {
  113. $this->app_key = $token['oauth_app_key'];
  114. }
  115. $this->app_secret = $config['APP_SECRET'];
  116. $this->callback = $config['CALLBACK'];
  117. $this->token = $token; //设置获取到的token
  118. }
  119. }
  120. /**
  121. * 取得Oauth实例
  122. *
  123. * @static
  124. *
  125. * @param $type
  126. * @param array $config
  127. * @param null $token
  128. *
  129. * @return mixed 返回Oauth
  130. * @throws Exception
  131. */
  132. public static function ins($type, $config = [], $token = null) {
  133. $_name = ucfirst(strtolower($type));
  134. $_class = '\\huolib\\oauth\\driver\\'.$_name;
  135. if (class_exists($_class)) {
  136. return new $_class($config, $token);
  137. } else {
  138. throw new Exception(lang('_CLASS_NOT_EXIST_').':'.$_name);
  139. }
  140. }
  141. /**
  142. * 用于保持请求和回调的状态,授权请求后原样带回给第三方。
  143. * 该参数可用于防止csrf攻击(跨站请求伪造攻击),
  144. * 建议第三方带上该参数,可设置为简单的随机数加session进行校验
  145. *
  146. * @return string
  147. */
  148. public function getState() {
  149. if (empty($this->state)) {
  150. $this->state = time();
  151. }
  152. return $this->state;
  153. }
  154. public function setState() {
  155. $this->state = md5(uniqid(rand(), true));
  156. Session::set('oauth.state', $this->state);
  157. }
  158. public function compareState($state) {
  159. //$_old_state = Session::get('state', 'oauth');
  160. $_old_state = Session::get('oauth.state');
  161. if ($_old_state != $state) {
  162. return false;
  163. }
  164. return true;
  165. }
  166. public function getToken() {
  167. return $this->token['expires_in'];
  168. }
  169. /**
  170. * @return string
  171. */
  172. public function getCallback() {
  173. return $this->callback;
  174. }
  175. /**
  176. * @param string $callback
  177. */
  178. public function setCallback($callback) {
  179. $this->callback = $callback;
  180. }
  181. /**
  182. * 获取指定API请求的URL
  183. *
  184. * @param string $api API名称
  185. * @param string $fix api后缀
  186. *
  187. * @return string 请求的完整URL
  188. */
  189. protected function url($api, $fix = '') {
  190. return $this->api_base.$api.$fix;
  191. }
  192. /**
  193. * 请求code
  194. *
  195. * @param string $display
  196. *
  197. */
  198. abstract public function getRequestCodeUrl($display = 'pc');
  199. /**
  200. * 获取access_token
  201. *
  202. * @param string $code 上一步请求到的code
  203. * @param null $extend
  204. *
  205. */
  206. abstract public function getAccessToken($code, $extend = null);
  207. /**
  208. * 抽象方法,在SNSSDK中实现
  209. * 组装接口调用参数 并调用接口
  210. *
  211. * @param string $api
  212. * @param string $param
  213. * @param string $method
  214. * @param bool $multi
  215. *
  216. */
  217. abstract protected function call($api, $param = '', $method = 'GET', $multi = false);
  218. /**
  219. * 抽象方法,在SNSSDK中实现
  220. * 解析access_token方法请求后的返回值
  221. *
  222. * @param $result
  223. * @param $extend
  224. *
  225. */
  226. abstract protected function parseToken($result, $extend);
  227. /**
  228. * 抽象方法,在SNSSDK中实现
  229. * 获取当前授权用户的SNS标识
  230. */
  231. abstract public function getOpenid();
  232. }