Passed
Push — master ( a4cd82...350c7c )
by ma
01:57
created

Huawei   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 73
c 1
b 0
f 0
dl 0
loc 146
rs 10
wmc 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
A parseToken() 0 7 2
A getUserInfo() 0 17 2
A userInfo() 0 15 1
A validateAccessToken() 0 14 2
A getToken() 0 13 3
A refreshToken() 0 17 2
A getRedirectUrl() 0 12 2
A openid() 0 4 1
1
<?php
2
/**
3
 * 华为开发者联盟 https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/dev-process-0000001050123523
4
 * api接口文档: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/server-api-api-0000001050123599
5
 */
6
namespace tinymeng\OAuth2\Gateways;
7
8
use tinymeng\OAuth2\Connector\Gateway;
9
use tinymeng\OAuth2\Exception\OAuthException;
10
use tinymeng\OAuth2\Helper\ConstCode;
11
12
class Huawei extends Gateway
13
{
14
    const API_BASE = 'https://oauth-login.cloud.huawei.com/';
15
    protected $AuthorizeURL = 'https://oauth-login.cloud.huawei.com/oauth2/v3/authorize';
16
    protected $AccessTokenURL = 'https://oauth-login.cloud.huawei.com/oauth2/v3/token';
17
    protected $UserInfoURL = 'https://oauth-api.cloud.huawei.com/rest.php';
18
19
    /**
20
     * 得到跳转地址
21
     */
22
    public function getRedirectUrl()
23
    {
24
        $this->saveState();
25
        $params = [
26
            'client_id'     => $this->config['app_id'],
27
            'redirect_uri'  => $this->config['callback'],
28
            'response_type' => $this->config['response_type'],
29
            'scope'         => $this->config['scope'] ?: 'openid profile',
30
            'state'         => $this->config['state'],
31
            'access_type'   => 'offline',
32
        ];
33
        return $this->AuthorizeURL . '?' . http_build_query($params);
34
    }
35
36
    /**
37
     * 获取当前授权用户的openid标识
38
     */
39
    public function openid()
40
    {
41
        $this->getToken();
42
        return $this->token['open_id'] ?? '';
43
    }
44
45
    /**
46
     * 获取格式化后的用户信息
47
     */
48
    public function userInfo()
49
    {
50
        $result = $this->getUserInfo();
51
        
52
        $userInfo = [
53
            'open_id'      => $this->openid(),
54
            'union_id'     => $this->token['union_id'] ?? '',
55
            'channel'      => ConstCode::TYPE_HUAWEI,
56
            'nickname'     => $result['displayName'] ?? '',
57
            'gender'       => ConstCode::GENDER,
58
            'avatar'       => $result['headPictureURL'] ?? '',
59
            'access_token' => $this->token['access_token'] ?? '',
60
            'native'       => $result
61
        ];
62
        return $userInfo;
63
    }
64
65
    /**
66
     * 获取原始接口返回的用户信息
67
     */
68
    public function getUserInfo()
69
    {
70
        $this->getToken();
71
        
72
        $params = [
73
            'method'       => 'oauth2/v3/userinfo',
74
            'access_token' => $this->token['access_token'],
75
            'nsp_ts'      => time(),
76
        ];
77
        
78
        $data = $this->get($this->UserInfoURL, $params);
79
        $data = json_decode($data, true);
80
        
81
        if (!isset($data['displayName'])) {
82
            throw new OAuthException('获取华为用户信息失败:' . json_encode($data));
83
        }
84
        return $data;
85
    }
86
87
    /**
88
     * 获取access_token
89
     */
90
    protected function getToken()
91
    {
92
        if (empty($this->token)) {
93
            $this->checkState();
94
            $params = [
95
                'client_id'     => $this->config['app_id'],
96
                'client_secret' => $this->config['app_secret'],
97
                'grant_type'    => $this->config['grant_type'],
98
                'code'          => isset($_REQUEST['code']) ? $_REQUEST['code'] : '',
99
                'redirect_uri'  => $this->config['callback'],
100
            ];
101
            $response = $this->post($this->AccessTokenURL, $params);
102
            $this->token = $this->parseToken($response);
103
        }
104
    }
105
106
    /**
107
     * 解析token
108
     */
109
    protected function parseToken($token)
110
    {
111
        $data = json_decode($token, true);
112
        if (isset($data['access_token'])) {
113
            return $data;
114
        }
115
        throw new OAuthException('获取华为 access_token 出错:' . json_encode($data));
116
    }
117
118
    /**
119
     * 检验授权凭证AccessToken是否有效
120
     */
121
    public function validateAccessToken($accessToken = null)
122
    {
123
        try {
124
            $accessToken = $accessToken ?? $this->token['access_token'];
125
            $params = [
126
                'method'       => 'oauth2/v3/tokeninfo',
127
                'access_token' => $accessToken,
128
                'nsp_ts'      => time(),
129
            ];
130
            $data = $this->get($this->UserInfoURL, $params);
131
            $data = json_decode($data, true);
132
            return isset($data['scope']);
133
        } catch (\Exception $e) {
134
            return false;
135
        }
136
    }
137
138
    /**
139
     * 刷新AccessToken续期
140
     */
141
    public function refreshToken($refreshToken)
142
    {
143
        $params = [
144
            'client_id'     => $this->config['app_id'],
145
            'client_secret' => $this->config['app_secret'],
146
            'grant_type'    => 'refresh_token',
147
            'refresh_token' => $refreshToken,
148
        ];
149
        
150
        $token = $this->post($this->AccessTokenURL, $params);
151
        $token = $this->parseToken($token);
152
        
153
        if (isset($token['access_token'])) {
154
            $this->token = $token;
155
            return true;
156
        }
157
        return false;
158
    }
159
}