anerg2046 /
sns_auth
| 1 | <?php |
||
| 2 | |||
| 3 | namespace anerg\OAuth2\Gateways; |
||
| 4 | |||
| 5 | use anerg\OAuth2\Connector\Gateway; |
||
| 6 | |||
| 7 | class Qq extends Gateway |
||
| 8 | { |
||
| 9 | const API_BASE = 'https://graph.qq.com/'; |
||
| 10 | protected $AuthorizeURL = 'https://graph.qq.com/oauth2.0/authorize'; |
||
| 11 | protected $AccessTokenURL = 'https://graph.qq.com/oauth2.0/token'; |
||
| 12 | |||
| 13 | /** |
||
| 14 | * 构造函数 |
||
| 15 | * |
||
| 16 | * @param array $config |
||
| 17 | */ |
||
| 18 | public function __construct($config = null) |
||
| 19 | { |
||
| 20 | parent::__construct($config); |
||
| 21 | $this->clientParams(); |
||
| 22 | } |
||
| 23 | |||
| 24 | /** |
||
| 25 | * 设置客户端请求的参数 |
||
| 26 | * |
||
| 27 | * @return void |
||
| 28 | */ |
||
| 29 | private function clientParams() |
||
| 30 | { |
||
| 31 | if (isset($this->config['access_token']) && !empty($this->config['access_token'])) { |
||
| 32 | $this->token['access_token'] = $this->config['access_token']; |
||
| 33 | } |
||
| 34 | } |
||
| 35 | |||
| 36 | /** |
||
| 37 | * 得到跳转地址 |
||
| 38 | */ |
||
| 39 | public function getRedirectUrl() |
||
| 40 | { |
||
| 41 | $params = [ |
||
| 42 | 'response_type' => $this->config['response_type'], |
||
| 43 | 'client_id' => $this->config['app_id'], |
||
| 44 | 'redirect_uri' => $this->config['callback'], |
||
| 45 | 'state' => $this->config['state'], |
||
| 46 | 'scope' => $this->config['scope'], |
||
| 47 | 'display' => $this->display, |
||
| 48 | ]; |
||
| 49 | return $this->AuthorizeURL . '?' . http_build_query($params); |
||
| 50 | } |
||
| 51 | |||
| 52 | /** |
||
| 53 | * 获取当前授权用户的openid标识 |
||
| 54 | */ |
||
| 55 | public function openid() |
||
| 56 | { |
||
| 57 | |||
| 58 | $this->getToken(); |
||
| 59 | |||
| 60 | if (!isset($this->token['openid']) || !$this->token['openid']) { |
||
| 61 | $userID = $this->getOpenID(); |
||
| 62 | $this->token['openid'] = $userID['openid']; |
||
| 63 | $this->token['unionid'] = isset($userID['unionid']) ? $userID['unionid'] : ''; |
||
| 64 | } |
||
| 65 | |||
| 66 | return $this->token['openid']; |
||
| 67 | } |
||
| 68 | |||
| 69 | /** |
||
| 70 | * 获取格式化后的用户信息 |
||
| 71 | */ |
||
| 72 | public function userinfo() |
||
| 73 | { |
||
| 74 | $rsp = $this->userinfoRaw(); |
||
| 75 | |||
| 76 | $avatar = $rsp['figureurl_qq_2'] ?: $rsp['figureurl_qq_1']; |
||
| 77 | if ($avatar) { |
||
| 78 | $avatar = \preg_replace('~\/\d+$~', '/0', $avatar); |
||
| 79 | } |
||
| 80 | |||
| 81 | $userinfo = [ |
||
| 82 | 'openid' => $openid = $this->openid(), |
||
|
0 ignored issues
–
show
Unused Code
introduced
by
Loading history...
|
|||
| 83 | 'unionid' => isset($this->token['unionid']) ? $this->token['unionid'] : '', |
||
| 84 | 'channel' => 'qq', |
||
| 85 | 'nick' => $rsp['nickname'], |
||
| 86 | 'gender' => $rsp['gender'] == "男" ? 'm' : 'f', |
||
| 87 | 'avatar' => $avatar, |
||
| 88 | ]; |
||
| 89 | return $userinfo; |
||
| 90 | } |
||
| 91 | |||
| 92 | /** |
||
| 93 | * 获取原始接口返回的用户信息 |
||
| 94 | */ |
||
| 95 | public function userinfoRaw() |
||
| 96 | { |
||
| 97 | return $this->call('user/get_user_info'); |
||
| 98 | } |
||
| 99 | |||
| 100 | /** |
||
| 101 | * 发起请求 |
||
| 102 | * |
||
| 103 | * @param string $api |
||
| 104 | * @param array $params |
||
| 105 | * @param string $method |
||
| 106 | * @return array |
||
| 107 | */ |
||
| 108 | private function call($api, $params = [], $method = 'GET') |
||
| 109 | { |
||
| 110 | $method = strtoupper($method); |
||
| 111 | |||
| 112 | $params['openid'] = $this->openid(); |
||
| 113 | $params['oauth_consumer_key'] = $this->config['app_id']; |
||
| 114 | $params['access_token'] = $this->token['access_token']; |
||
| 115 | $params['format'] = 'json'; |
||
| 116 | |||
| 117 | $data = $this->$method(self::API_BASE . $api, $params); |
||
| 118 | |||
| 119 | $ret = json_decode($data, true); |
||
| 120 | if ($ret['ret'] != 0) { |
||
| 121 | throw new \Exception("qq获取用户信息出错:" . $ret['msg']); |
||
| 122 | } |
||
| 123 | return $ret; |
||
| 124 | } |
||
| 125 | |||
| 126 | /** |
||
| 127 | * 解析access_token方法请求后的返回值 |
||
| 128 | * @param string $token 获取access_token的方法的返回值 |
||
| 129 | */ |
||
| 130 | protected function parseToken($token) |
||
| 131 | { |
||
| 132 | parse_str($token, $data); |
||
| 133 | if (isset($data['access_token'])) { |
||
| 134 | return $data; |
||
| 135 | } else { |
||
| 136 | throw new \Exception("获取腾讯QQ ACCESS_TOKEN 出错:" . $token); |
||
| 137 | } |
||
| 138 | } |
||
| 139 | |||
| 140 | /** |
||
| 141 | * 通过接口获取openid |
||
| 142 | * |
||
| 143 | * @return string |
||
| 144 | */ |
||
| 145 | private function getOpenID() |
||
| 146 | { |
||
| 147 | $client = new \GuzzleHttp\Client(); |
||
| 148 | |||
| 149 | $query = ['access_token' => $this->token['access_token']]; |
||
| 150 | // 如果要获取unionid,先去申请:http://wiki.connect.qq.com/%E5%BC%80%E5%8F%91%E8%80%85%E5%8F%8D%E9%A6%88 |
||
| 151 | if (isset($this->config['withUnionid']) && $this->config['withUnionid'] === true) { |
||
| 152 | $query['unionid'] = 1; |
||
| 153 | } |
||
| 154 | |||
| 155 | $response = $client->request('GET', self::API_BASE . 'oauth2.0/me', ['query' => $query]); |
||
| 156 | $data = $response->getBody()->getContents(); |
||
| 157 | $data = json_decode(trim(substr($data, 9), " );\n"), true); |
||
| 158 | if (isset($data['openid'])) { |
||
| 159 | return $data; |
||
| 160 | } else { |
||
| 161 | throw new \Exception("获取用户openid出错:" . $data['error_description']); |
||
| 162 | } |
||
| 163 | } |
||
| 164 | } |
||
| 165 |