anerg2046 /
sns_auth
| 1 | <?php |
||
| 2 | |||
| 3 | namespace anerg\OAuth2\Gateways; |
||
| 4 | |||
| 5 | use anerg\OAuth2\Connector\Gateway; |
||
| 6 | use anerg\OAuth2\Helper\Str; |
||
| 7 | |||
| 8 | class Twitter extends Gateway |
||
| 9 | { |
||
| 10 | const API_BASE = 'https://api.twitter.com/'; |
||
| 11 | |||
| 12 | private $tokenSecret = ''; |
||
| 13 | |||
| 14 | /** |
||
| 15 | * 构造函数 |
||
| 16 | * |
||
| 17 | * @param array $config |
||
| 18 | */ |
||
| 19 | public function __construct($config = null) |
||
| 20 | { |
||
| 21 | parent::__construct($config); |
||
| 22 | $this->clientParams(); |
||
| 23 | } |
||
| 24 | |||
| 25 | /** |
||
| 26 | * 设置客户端请求的参数 |
||
| 27 | * |
||
| 28 | * @return void |
||
| 29 | */ |
||
| 30 | private function clientParams() |
||
| 31 | { |
||
| 32 | if (isset($this->config['oauth_token']) && !empty($this->config['oauth_token'])) { |
||
| 33 | $this->token['oauth_token'] = $this->config['oauth_token']; |
||
| 34 | } |
||
| 35 | if (isset($this->config['oauth_token_secret']) && !empty($this->config['oauth_token_secret'])) { |
||
| 36 | $this->token['oauth_token_secret'] = $this->config['oauth_token_secret']; |
||
| 37 | $this->tokenSecret = $this->config['oauth_token_secret']; |
||
| 38 | } |
||
| 39 | if (isset($this->config['user_id']) && !empty($this->config['user_id'])) { |
||
| 40 | $this->token['user_id'] = $this->config['user_id']; |
||
| 41 | } |
||
| 42 | if (isset($this->config['screen_name']) && !empty($this->config['screen_name'])) { |
||
| 43 | $this->token['screen_name'] = $this->config['screen_name']; |
||
| 44 | } |
||
| 45 | } |
||
| 46 | /** |
||
| 47 | * 得到跳转地址 |
||
| 48 | */ |
||
| 49 | public function getRedirectUrl() |
||
| 50 | { |
||
| 51 | $oauthToken = $this->call('oauth/request_token', ['oauth_callback' => $this->config['callback']], 'POST'); |
||
| 52 | return self::API_BASE . 'oauth/authenticate?oauth_token=' . $oauthToken['oauth_token']; |
||
| 53 | } |
||
| 54 | |||
| 55 | /** |
||
| 56 | * 获取当前授权用户的openid标识 |
||
| 57 | */ |
||
| 58 | public function openid() |
||
| 59 | { |
||
| 60 | $data = $this->userinfoRaw(); |
||
| 61 | return $data['id_str']; |
||
| 62 | } |
||
| 63 | |||
| 64 | /** |
||
| 65 | * 获取格式化后的用户信息 |
||
| 66 | */ |
||
| 67 | public function userinfo() |
||
| 68 | { |
||
| 69 | $data = $this->userinfoRaw(); |
||
| 70 | |||
| 71 | $return = [ |
||
| 72 | 'openid' => $data['id_str'], |
||
| 73 | 'channel' => 'twitter', |
||
| 74 | 'nick' => $data['name'], |
||
| 75 | 'gender' => 'n', //twitter不返回用户性别 |
||
| 76 | 'avatar' => $data['profile_image_url_https'], |
||
| 77 | ]; |
||
| 78 | return $return; |
||
| 79 | } |
||
| 80 | |||
| 81 | /** |
||
| 82 | * 获取原始接口返回的用户信息 |
||
| 83 | */ |
||
| 84 | public function userinfoRaw() |
||
| 85 | { |
||
| 86 | if (!$this->token) { |
||
|
0 ignored issues
–
show
|
|||
| 87 | $this->token = $this->getAccessToken(); |
||
| 88 | if (isset($this->token['oauth_token_secret'])) { |
||
| 89 | $this->tokenSecret = $this->token['oauth_token_secret']; |
||
| 90 | } else { |
||
| 91 | throw new \Exception("获取Twitter ACCESS_TOKEN 出错:" . json_encode($this->token)); |
||
| 92 | } |
||
| 93 | } |
||
| 94 | |||
| 95 | return $this->call('1.1/users/show.json', $this->token, 'GET', true); |
||
| 96 | } |
||
| 97 | |||
| 98 | /** |
||
| 99 | * 发起请求 |
||
| 100 | * |
||
| 101 | * @param string $api |
||
| 102 | * @param array $params |
||
| 103 | * @param string $method |
||
| 104 | * @return array |
||
| 105 | */ |
||
| 106 | private function call($api, $params = [], $method = 'GET', $isJson = false) |
||
| 107 | { |
||
| 108 | $method = strtoupper($method); |
||
| 109 | $request = [ |
||
| 110 | 'method' => $method, |
||
| 111 | 'uri' => self::API_BASE . $api, |
||
| 112 | ]; |
||
| 113 | $oauthParams = $this->getOAuthParams($params); |
||
| 114 | $oauthParams['oauth_signature'] = $this->signature($request, $oauthParams); |
||
| 115 | |||
| 116 | $headers = ['Authorization' => $this->getAuthorizationHeader($oauthParams)]; |
||
| 117 | |||
| 118 | $data = $this->$method($request['uri'], $params, $headers); |
||
| 119 | if ($isJson) { |
||
| 120 | return json_decode($data, true); |
||
| 121 | } |
||
| 122 | parse_str($data, $data); |
||
| 123 | return $data; |
||
| 124 | } |
||
| 125 | |||
| 126 | /** |
||
| 127 | * 获取oauth参数 |
||
| 128 | * |
||
| 129 | * @param array $params |
||
| 130 | * @return array |
||
| 131 | */ |
||
| 132 | private function getOAuthParams($params = []) |
||
| 133 | { |
||
| 134 | $_default = [ |
||
| 135 | 'oauth_consumer_key' => $this->config['app_id'], |
||
| 136 | 'oauth_nonce' => Str::random(), |
||
| 137 | 'oauth_signature_method' => 'HMAC-SHA1', |
||
| 138 | 'oauth_timestamp' => $this->timestamp, |
||
| 139 | 'oauth_token' => '', |
||
| 140 | 'oauth_version' => '1.0', |
||
| 141 | ]; |
||
| 142 | return array_merge($_default, $params); |
||
| 143 | } |
||
| 144 | |||
| 145 | /** |
||
| 146 | * 签名操作 |
||
| 147 | * |
||
| 148 | * @param array $request |
||
| 149 | * @param array $params |
||
| 150 | * @return string |
||
| 151 | */ |
||
| 152 | private function signature($request, $params = []) |
||
| 153 | { |
||
| 154 | ksort($params); |
||
| 155 | $sign_str = Str::buildParams($params, true); |
||
| 156 | $sign_str = $request['method'] . '&' . rawurlencode($request['uri']) . '&' . rawurlencode($sign_str); |
||
| 157 | $sign_key = $this->config['app_secret'] . '&' . $this->tokenSecret; |
||
| 158 | |||
| 159 | return rawurlencode(base64_encode(hash_hmac('sha1', $sign_str, $sign_key, true))); |
||
| 160 | } |
||
| 161 | |||
| 162 | /** |
||
| 163 | * 获取请求附带的Header头信息 |
||
| 164 | * |
||
| 165 | * @param array $params |
||
| 166 | * @return string |
||
| 167 | */ |
||
| 168 | private function getAuthorizationHeader($params) |
||
| 169 | { |
||
| 170 | $return = 'OAuth '; |
||
| 171 | foreach ($params as $k => $param) { |
||
| 172 | $return .= $k . '="' . $param . '", '; |
||
| 173 | } |
||
| 174 | return rtrim($return, ', '); |
||
| 175 | } |
||
| 176 | |||
| 177 | /** |
||
| 178 | * 获取access token |
||
| 179 | * twitter不是标准的oauth2 |
||
| 180 | * |
||
| 181 | * @return array |
||
| 182 | */ |
||
| 183 | protected function getAccessToken() |
||
| 184 | { |
||
| 185 | return $this->call('oauth/access_token', $_GET, 'POST'); |
||
| 186 | } |
||
| 187 | } |
||
| 188 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)or! empty(...)instead.