Weibo.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php
  2. /**
  3. * Weibo.php UTF-8
  4. * 新浪微博登陆Api
  5. *
  6. * @date : 2018/4/25 16:27
  7. *
  8. * @license 这不是一个自由软件,未经授权不许任何使用和传播。
  9. * @author : wuyonghong <wyh@huosdk.com>
  10. * @version : HUOSDK 8.0
  11. * http://open.weibo.com/wiki/Connect/login
  12. */
  13. namespace huolib\oauth\driver;
  14. use huolib\constant\MemConst;
  15. use huolib\oauth\OAuth;
  16. use huolib\tool\Http;
  17. use think\Exception;
  18. class Weibo extends OAuth {
  19. /**
  20. * 获取requestCode的api接口
  21. *
  22. * @var string
  23. */
  24. protected $request_code_url = 'https://api.weibo.com/oauth2/authorize';
  25. /**
  26. * mobile请求地址
  27. *
  28. * @var string
  29. */
  30. protected $request_code_url_m = 'https://open.weibo.cn/oauth2/authorize ';
  31. /**
  32. * 获取Access token的api接口
  33. *
  34. * @var String
  35. */
  36. protected $access_token_url = 'https://api.weibo.com/oauth2/access_token';
  37. /**
  38. * API根路径
  39. *
  40. * @var string
  41. */
  42. protected $api_base = 'https://api.weibo.com/2/';
  43. /**
  44. * 获取request_code的额外参数 URL查询字符串格式
  45. *
  46. * @var string
  47. */
  48. protected $authorize = 'snsapi_login';
  49. /**
  50. * Weibo constructor.
  51. *
  52. * @param array $config
  53. * @param array|null $token
  54. *
  55. * @throws \think\Exception
  56. */
  57. public function __construct(array $config = [], array $token = null) {
  58. $_config = $config;
  59. if (empty($config)) {
  60. if (file_exists(GLOBAL_CONF_PATH."extra/oauth/weibo.php")) {
  61. $_config = include GLOBAL_CONF_PATH."extra/oauth/weibo.php";
  62. } else {
  63. $_config = array();
  64. }
  65. }
  66. parent::__construct($_config, $token);
  67. }
  68. /**
  69. * 第一步:请求CODE 跳转URL
  70. * 请求Authorize访问地址
  71. *
  72. * @param string $display
  73. *
  74. * @return string 跳转地址
  75. * http://open.weibo.com/wiki/Oauth2/authorize
  76. * @return string
  77. */
  78. public function getRequestCodeUrl($display = 'pc') {
  79. $_display = $display;
  80. if ('pc' == $_display) {
  81. $_display = 'default';
  82. $_request_code_url = $this->request_code_url;
  83. } else {
  84. $_display = 'mobile';
  85. $_request_code_url = $this->request_code_url_m;
  86. }
  87. $params = array(
  88. 'client_id' => $this->app_key,
  89. 'redirect_uri' => $this->callback,
  90. 'state' => $this->getState(),
  91. 'scope' => $this->authorize,
  92. 'display' => $_display,
  93. 'forcelogin' => 'false'
  94. );
  95. return $_request_code_url.'?'.http_build_query($params);
  96. }
  97. /**
  98. * 第二步:通过code获取access_token
  99. * http://open.weibo.com/wiki/Oauth2/access_token
  100. *
  101. * @param $code
  102. * @param null $extend
  103. *
  104. * @return array|null
  105. * @throws Exception
  106. */
  107. public function getAccessToken($code, $extend = null) {
  108. $_params = array(
  109. 'client_id' => $this->app_key,
  110. 'client_secret' => $this->app_secret,
  111. 'grant_type' => $this->grant_type,
  112. 'code' => $code,
  113. 'redirect_uri' => $this->callback,
  114. );
  115. $_rdata = Http::post($this->access_token_url, $_params);
  116. $this->token = $this->parseToken($_rdata);
  117. return $this->token;
  118. }
  119. /**
  120. * 第三步:通过access_token调用接口
  121. *
  122. * @param string $api API
  123. * @param string $param 调用API的额外参数
  124. * @param string $method HTTP请求方法 默认为GET
  125. * @param null $multi
  126. *
  127. * @return mixed
  128. * @throws Exception
  129. */
  130. public function call($api, $param = '', $method = 'GET', $multi = null) {
  131. $params = array(
  132. 'access_token' => $this->token['access_token'],
  133. 'uid' => $this->getOpenid(),
  134. );
  135. $data = Http::request($this->url($api), $params, $method);
  136. return json_decode($data, true);
  137. }
  138. /**
  139. * 获取授权用户的用户信息
  140. *
  141. * @return array
  142. * @throws \Exception
  143. * http://open.weibo.com/wiki/2/users/show
  144. *
  145. * id int64 用户UID
  146. * idstr string 字符串型的用户UID
  147. * screen_name string 用户昵称
  148. * name string 友好显示名称
  149. * province int 用户所在省级ID
  150. * city int 用户所在城市ID
  151. * location string 用户所在地
  152. * description string 用户个人描述
  153. * url string 用户博客地址
  154. * profile_image_url string 用户头像地址(中图),50×50像素
  155. * profile_url string 用户的微博统一URL地址
  156. * domain string 用户的个性化域名
  157. * weihao string 用户的微号
  158. * gender string 性别,m:男、f:女、n:未知
  159. * followers_count int 粉丝数
  160. * friends_count int 关注数
  161. * statuses_count int 微博数
  162. * favourites_count int 收藏数
  163. * created_at string 用户创建(注册)时间
  164. * following boolean 暂未支持
  165. * allow_all_act_msg boolean 是否允许所有人给我发私信,true:是,false:否
  166. * geo_enabled boolean 是否允许标识用户的地理位置,true:是,false:否
  167. * verified boolean 是否是微博认证用户,即加V用户,true:是,false:否
  168. * verified_type int 暂未支持
  169. * remark string 用户备注信息,只有在查询用户关系时才返回此字段
  170. * status object 用户的最近一条微博信息字段 详细
  171. * allow_all_comment boolean 是否允许所有人对我的微博进行评论,true:是,false:否
  172. * avatar_large string 用户头像地址(大图),180×180像素
  173. * avatar_hd string 用户头像地址(高清),高清头像原图
  174. * verified_reason string 认证原因
  175. * follow_me boolean 该用户是否关注当前登录用户,true:是,false:否
  176. * online_status int 用户的在线状态,0:不在线、1:在线
  177. * bi_followers_count int 用户的互粉数
  178. * lang string 用户当前的语言版本,zh-cn:简体中文,zh-tw:繁体中文,en:英语
  179. *
  180. */
  181. public function getUserInfo() {
  182. $_response = $this->call('users/show.json');
  183. if (empty($_response) || (isset($_response['error_code']) && $_response['error_code'] != 0)) {
  184. throw new Exception('接口访问失败!'.$_response['error']);
  185. } else {
  186. $_oauth_data = array(
  187. 'openid' => $_response['id'],
  188. 'unionid' => isset($_response['idstr']) ? $_response['idstr'] : '',
  189. 'channel' => 'weibo',
  190. 'nickname' => $_response['name'],
  191. 'gender' => $this->getGender($_response['gender']),
  192. 'avatar' => $_response['avatar_large'],
  193. 'token' => $this->token
  194. );
  195. return $_oauth_data;
  196. }
  197. }
  198. /**
  199. * 获取当前授权用户的SNS标识
  200. *
  201. * @throws Exception
  202. */
  203. public function getOpenid() {
  204. $_data = $this->token;
  205. if (isset($_data['uid'])) {
  206. return $_data['uid'];
  207. } else {
  208. throw new Exception('没有获取到微博用户ID!');
  209. }
  210. }
  211. /**
  212. * 解析access_token方法请求后的返回值
  213. *
  214. * @param $result
  215. * @param null $extend
  216. *
  217. * @return mixed
  218. * @throws Exception
  219. */
  220. protected function parseToken($result, $extend = null) {
  221. $_rdata = json_decode($result, true);
  222. if ($_rdata['access_token'] && $_rdata['expires_in']) {
  223. $this->token = $_rdata;
  224. $_rdata['openid'] = $this->getOpenid();
  225. return $_rdata;
  226. } else {
  227. throw new Exception("获取微博 ACCESS_token 出错:{$result}");
  228. }
  229. }
  230. /**
  231. * @param string $gender
  232. *
  233. * @return int
  234. */
  235. private function getGender($gender = 'm') {
  236. switch ($gender) {
  237. case 'm':
  238. return MemConst::GENDER_M;
  239. case 'f':
  240. return MemConst::GENDER_F;
  241. default :
  242. return MemConst::GENDER_N;
  243. }
  244. }
  245. }