Douyin::parseUserInfo()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
dl 0
loc 7
rs 10
c 1
b 0
f 0
cc 3
nc 2
nop 1
1
<?php
2
/**
3
 * 网站应用抖音登录开发 https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/account-permission/douyin-get-permission-code
4
 * 抖音小程序开发 https://developer.open-douyin.com/docs/resource/zh-CN/mini-game/develop/server/log-in/code-2-session/
5
 * 注: scope值
6
 *      1、以 trial.whitelist 放平台里申请了白名单用户一直显示待绑定,请查看https://developer.open-douyin.com/docs/resource/zh-CN/dop/common-question/faq/
7
 *      2、以 user_info为scope发起的网页授权,是用来获取用户的基本信息的。
8
 *      3、以 login_id为scope静默授权。
9
 * 如想打通unionid的话需要将小程序绑定到同一个抖音开放平台
10
 */
11
namespace tinymeng\OAuth2\Gateways;
12
13
use tinymeng\OAuth2\Connector\Gateway;
14
use tinymeng\OAuth2\Exception\OAuthException;
15
use tinymeng\OAuth2\Helper\ConstCode;
16
17
/**
18
 * Class Douyin
19
 * @package tinymeng\OAuth2\Gateways
20
 * @Author: TinyMeng <[email protected]>
21
 * @Created: 2018/11/9
22
 */
23
class Douyin extends Gateway
24
{
25
    protected $ApiBase            = 'https://open.douyin.com';
26
    protected $AuthorizeURL   = 'https://open.douyin.com/platform/oauth/connect/';
27
    protected $AuthorizeSilenceURL   = 'https://open.douyin.com/oauth/authorize/v2/';//抖音静默授权
28
    protected $AccessTokenURL = 'oauth/access_token/';
29
    protected $UserInfoURL = 'oauth/userinfo/';
30
31
    protected $jsCode2Session = 'https://minigame.zijieapi.com/mgplatform/api/apps/jscode2session';
32
33
    protected $API_BASE_ARRAY = [
34
        'douyin'=>'https://open.douyin.com/',//抖音
35
        'toutiao'=>'https://open.snssdk.com/',//头条
36
        'xigua'=>'https://open-api.ixigua.com/',//西瓜
37
    ];
38
39
    public $oauth_type = ConstCode::TYPE_DOUYIN;//抖音
40
41
    /**
42
     * @param $config
43
     * @throws OAuthException
44
     */
45
    public function __construct($config)
46
    {
47
        parent::__construct($config);
48
        //切换方式
49
        $this->switchAccessTokenURL();
50
    }
51
52
    /**
53
     * Description:  得到跳转地址
54
     * @author: JiaMeng <[email protected]>
55
     * Updater:
56
     * @return string
57
     */
58
    public function getRedirectUrl()
59
    {
60
        //存储state
61
        $this->saveState();
62
63
        //登录参数
64
        $params = [
65
            'client_key'    => $this->config['app_id'],
66
            'redirect_uri'  => $this->config['callback'],
67
            'response_type' => $this->config['response_type'],
68
            'scope'         => $this->config['scope'],
69
            'optionalScope' => $this->config['optionalScope']??'',
70
            'state'         => $this->config['state'],
71
        ];
72
        if($params['state'] == 'login_id'){
73
            /**
74
             * 抖音静默获取授权码
75
             * https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/account-permission/douyin-default-get-permission-code
76
             */
77
            return $this->AuthorizeSilenceURL . '?' . http_build_query($params);
78
        }else{
79
            return $this->AuthorizeURL . '?' . http_build_query($params);
80
        }
81
    }
82
83
    /**
84
     * Description:  获取当前授权用户的openid标识
85
     * @author: JiaMeng <[email protected]>
86
     * Updater:
87
     * @return mixed
88
     * @throws OAuthException
89
     */
90
    public function openid()
91
    {
92
        $this->getToken();
93
94
        if (isset($this->token['open_id'])) {
95
            return $this->token['open_id'];
96
        } else {
97
            throw new OAuthException('没有获取到抖音用户ID!');
98
        }
99
    }
100
101
    /**
102
     * Description:  获取格式化后的用户信息
103
     * @return array
104
     * @throws OAuthException
105
     * @author: JiaMeng <[email protected]>
106
     * Updater:
107
     */
108
    public function userInfo()
109
    {
110
        //登录参数
111
        $result = $this->getUserInfo();
112
113
        $userInfo = [
114
            'open_id' => $this->openid(),
115
            'access_token'=> $this->token['access_token'] ?? '',
116
            'union_id'=> $this->token['unionid'] ?? '',
117
            'channel' => $this->oauth_type,
118
            'nickname'=> $result['nickname']??'',
119
            'gender'  => $result['gender'] ?? ConstCode::GENDER,
120
            'type'  => ConstCode::getTypeConst($this->oauth_type,$this->type),
121
            'avatar'  => $result['avatar']??'',
122
            'native'   => $result,
123
        ];
124
        return $userInfo;
125
    }
126
127
    /**
128
     * Description:  获取原始接口返回的用户信息
129
     * @return array
130
     * @throws OAuthException
131
     * @author: JiaMeng <[email protected]>
132
     * Updater:
133
     */
134
    public function getUserInfo()
135
    {
136
        if($this->type == 'app'){//App登录
137
            if(!isset($_REQUEST['access_token']) ){
138
                throw new OAuthException("Douyin APP登录 需要传输access_token参数! ");
139
            }
140
            $this->token['access_token'] = $_REQUEST['access_token'];
141
        }elseif ($this->type == 'applets'){
142
            //小程序
143
            return $this->applets();
144
        }else {
145
            /** 获取token信息 */
146
            $this->getToken();
147
        }
148
149
        /** 获取用户信息 */
150
        $params = [
151
            'access_token'=>$this->token['access_token'],
152
            'open_id'=>$this->openid(),
153
        ];
154
        $data = $this->get($this->UserInfoURL, $params);
155
156
        return $this->parseUserInfo($data);
157
    }
158
159
    /**
160
     * @return array|mixed|null
161
     * @throws OAuthException
162
     */
163
    public function applets(){
164
        /** 获取参数 */
165
        $params = $this->jscode2sessionParams();
166
167
        /** 获取access_token */
168
        $token =  $this->get($this->jsCode2Session, $params);
169
        /** 解析token值(子类实现此方法) */
170
        $this->token = $this->parseToken($token);
171
        return $this->token;
172
    }
173
174
    /**
175
     * Description:  根据第三方授权页面样式切换跳转地址
176
     * @author: JiaMeng <[email protected]>
177
     * Updater:
178
     */
179
    private function switchAccessTokenURL()
180
    {
181
        switch ($this->oauth_type){
182
            case ConstCode::TYPE_DOUYIN:$this->ApiBase = $this->API_BASE_ARRAY['douyin'];break;
183
            case ConstCode::TYPE_TOUTIAO:$this->ApiBase = $this->API_BASE_ARRAY['toutiao'];break;
184
            case ConstCode::TYPE_XIGUA:$this->ApiBase = $this->API_BASE_ARRAY['xigua'];break;
185
            default:throw new OAuthException("获取抖音 OAUTH_TYPE 参数出错:{$this->oauth_type}");
186
        }
187
        $this->AccessTokenURL = $this->ApiBase.$this->AccessTokenURL;
188
        $this->UserInfoURL = $this->ApiBase.$this->UserInfoURL;
189
    }
190
191
    /**
192
     * Description:  重写 获取的AccessToken请求参数
193
     * @author: JiaMeng <[email protected]>
194
     * Updater:
195
     * @return array
196
     */
197
    protected function accessTokenParams()
198
    {
199
        $params = [
200
            'client_key'      => $this->config['app_id'],
201
            'client_secret'     => $this->config['app_secret'],
202
            'grant_type' => $this->config['grant_type'],
203
            'code'       => $this->getCode(),
204
        ];
205
206
        return $params;
207
    }
208
209
    /**
210
     * Description:  重写 获取的jscode2sessionParams请求参数
211
     * @author: JiaMeng <[email protected]>
212
     * Updater:
213
     * @return array
214
     */
215
    protected function jscode2sessionParams()
216
    {
217
        $params = [
218
            'appid'      => $this->config['app_id'],
219
            'secret'     => $this->config['app_secret'],
220
        ];
221
        if(isset($_REQUEST['code'])) $params['code'] = $_REQUEST['code'];
222
        if(isset($_REQUEST['anonymous_code'])) $params['anonymous_code'] = $_REQUEST['anonymous_code'];
223
224
        return $params;
225
    }
226
227
    /**
228
     * Description:  解析access_token方法请求后的返回值
229
     * @author: JiaMeng <[email protected]>
230
     * Updater:
231
     * @param string $token 获取access_token的方法的返回值
232
     * @return mixed
233
     * @throws OAuthException
234
     */
235
    protected function parseToken($token)
236
    {
237
        $data = json_decode($token, true);
238
        if (isset($data['data']['access_token'])) {
239
            return $data['data'];
240
        }elseif (isset($data['session_key'])){
241
            //小程序登录
242
            return $data;
243
        } else {
244
            throw new OAuthException("获取抖音 ACCESS_TOKEN 出错:{$token}");
245
        }
246
    }
247
248
    /**
249
     * Description:  解析access_token方法请求后的返回值
250
     * @author: JiaMeng <[email protected]>
251
     * Updater:
252
     * @param string $token 获取access_token的方法的返回值
253
     * @return mixed
254
     * @throws OAuthException
255
     */
256
    protected function parseUserInfo($data)
257
    {
258
        $data = json_decode($data, true);
259
        if (isset($data['message']) && $data['message'] == 'success') {
260
            return $data['data'];
261
        } else {
262
            throw new OAuthException("获取抖音 UserInfo 出错:{$data['data']['description']}");
263
        }
264
    }
265
266
}
267