Passed
Push — master ( 7d7f87...8d60a4 )
by ma
01:36
created

Twitter::call()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 18
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 4
1
<?php
2
3
namespace tinymeng\OAuth2\Gateways;
4
5
use tinymeng\OAuth2\Connector\Gateway;
6
use tinymeng\OAuth2\Helper\ConstCode;
7
use tinymeng\OAuth2\Helper\Str;
8
9
/**
10
 * Class Twitter
11
 * @package tinymeng\OAuth2\Gateways
12
 * @Author: TinyMeng <[email protected]>
13
 * @Created: 2018/11/9
14
 */
15
class Twitter extends Gateway
16
{
17
    const API_BASE = 'https://api.twitter.com/';
18
19
    private $tokenSecret = '';
20
21
    /**
22
     * 得到跳转地址
23
     */
24
    public function getRedirectUrl()
25
    {
26
        //存储state
27
        $this->saveState();
28
        //登录参数
29
        $oauthToken = $this->call('oauth/request_token', ['oauth_callback' => $this->config['callback']], 'POST');
30
        return self::API_BASE . 'oauth/authenticate?oauth_token=' . $oauthToken['oauth_token'];
31
    }
32
33
    /**
34
     * 获取当前授权用户的openid标识
35
     */
36
    public function openid()
37
    {
38
        $data = $this->getUserInfo();
39
        return $data['id_str'];
40
    }
41
42
    /**
43
     * 获取格式化后的用户信息
44
     */
45
    public function userInfo()
46
    {
47
        $data = $this->getUserInfo();
48
49
        $userInfo = [
50
            'open_id'  => $data['id_str'],
51
            'channel' => ConstCode::TYPE_TWITTER,
52
            'nickname'    => $data['name'],
53
            'gender'  => ConstCode::GENDER, //twitter不返回用户性别
54
            'avatar'  => $data['profile_image_url_https'],
55
        ];
56
        return $userInfo;
57
    }
58
59
    /**
60
     * 获取原始接口返回的用户信息
61
     */
62
    public function getUserInfo()
63
    {
64
        if (empty($this->token)) {
65
            $this->token = $this->getAccessToken();
66
            if (isset($this->token['oauth_token_secret'])) {
67
                $this->tokenSecret = $this->token['oauth_token_secret'];
68
            } else {
69
                throw new \Exception("获取Twitter ACCESS_TOKEN 出错:" . json_encode($this->token));
70
            }
71
        }
72
73
        return $this->call('1.1/account/verify_credentials.json', $this->token, 'GET', true);
74
    }
75
76
    /**
77
     * 发起请求
78
     *
79
     * @param string $api
80
     * @param array $params
81
     * @param string $method
82
     * @return array
83
     */
84
    private function call($api, $params = [], $method = 'GET', $isJson = false)
85
    {
86
        $method  = strtoupper($method);
87
        $request = [
88
            'method' => $method,
89
            'uri'    => self::API_BASE . $api,
90
        ];
91
        $oauthParams                    = $this->getOAuthParams($params);
92
        $oauthParams['oauth_signature'] = $this->signature($request, $oauthParams);
93
94
        $headers = ['Authorization' => $this->getAuthorizationHeader($oauthParams)];
95
96
        $data = $this->$method($request['uri'], $params, $headers);
97
        if ($isJson) {
98
            return json_decode($data, true);
99
        }
100
        parse_str($data, $data);
101
        return $data;
102
    }
103
104
    /**
105
     * 获取oauth参数
106
     *
107
     * @param array $params
108
     * @return array
109
     */
110
    private function getOAuthParams($params = [])
111
    {
112
        $_default = [
113
            'oauth_consumer_key'     => $this->config['app_id'],
114
            'oauth_nonce'            => Str::random(),
115
            'oauth_signature_method' => 'HMAC-SHA1',
116
            'oauth_timestamp'        => $this->timestamp,
117
            'oauth_token'            => '',
118
            'oauth_version'          => '1.0',
119
        ];
120
        return array_merge($_default, $params);
121
    }
122
123
    /**
124
     * 签名操作
125
     *
126
     * @param array $request
127
     * @param array $params
128
     * @return string
129
     */
130
    private function signature($request, $params = [])
131
    {
132
        ksort($params);
133
        $sign_str = Str::buildParams($params, true);
134
        $sign_str = $request['method'] . '&' . rawurlencode($request['uri']) . '&' . rawurlencode($sign_str);
135
        $sign_key = $this->config['app_secret'] . '&' . $this->tokenSecret;
136
137
        return rawurlencode(base64_encode(hash_hmac('sha1', $sign_str, $sign_key, true)));
138
    }
139
140
    /**
141
     * 获取请求附带的Header头信息
142
     *
143
     * @param array $params
144
     * @return string
145
     */
146
    private function getAuthorizationHeader($params)
147
    {
148
        $return = 'OAuth ';
149
        foreach ($params as $k => $param) {
150
            $return .= $k . '="' . $param . '", ';
151
        }
152
        return rtrim($return, ', ');
153
    }
154
155
156
    /**
157
     * Description:  getAccessToken
158
     * @author: JiaMeng <[email protected]>
159
     * Updater:
160
     * @return array
161
     */
162
    protected function getAccessToken()
163
    {
164
        return $this->call('oauth/access_token', $_GET, 'POST');
165
    }
166
167
    /**
168
     * 解析access_token方法请求后的返回值
169
     * @param string $token 获取access_token的方法的返回值
170
     */
171
    protected function parseToken($token){
172
        return $token;
173
    }
174
}
175