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

Microsoft::userInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 11
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 15
rs 9.9
1
<?php
2
/**
3
 * Microsoft Identity Platform
4
 * https://docs.microsoft.com/en-us/azure/active-directory/develop/
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 Microsoft extends Gateway
13
{
14
    const API_BASE = 'https://login.microsoftonline.com/';
15
    protected $AuthorizeURL = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
16
    protected $AccessTokenURL = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
17
    protected $UserInfoURL = 'https://graph.microsoft.com/v1.0/me';
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'] ?: 'User.Read',
30
            'state'         => $this->config['state'],
31
            'response_mode' => 'query',
32
        ];
33
        return $this->AuthorizeURL . '?' . http_build_query($params);
34
    }
35
36
    /**
37
     * 获取当前授权用户的openid标识
38
     */
39
    public function openid()
40
    {
41
        $result = $this->getUserInfo();
42
        return $result['id'] ?? '';
43
    }
44
45
    /**
46
     * 获取格式化后的用户信息
47
     */
48
    public function userInfo()
49
    {
50
        $result = $this->getUserInfo();
51
        
52
        $userInfo = [
53
            'open_id'      => $result['id'] ?? '',
54
            'union_id'     => $result['id'] ?? '',
55
            'channel'      => ConstCode::TYPE_MICROSOFT,
56
            'nickname'     => $result['displayName'] ?? '',
57
            'gender'       => ConstCode::GENDER,
58
            'avatar'       => '',
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
        $headers = [
73
            'Authorization: Bearer ' . $this->token['access_token'],
74
        ];
75
        
76
        $data = $this->get($this->UserInfoURL, [], $headers);
77
        $data = json_decode($data, true);
78
        
79
        if (!isset($data['id'])) {
80
            throw new OAuthException('获取Microsoft用户信息失败:' . json_encode($data));
81
        }
82
        return $data;
83
    }
84
85
    /**
86
     * 获取access_token
87
     */
88
    protected function getToken()
89
    {
90
        if (empty($this->token)) {
91
            $this->checkState();
92
            
93
            $params = [
94
                'client_id'     => $this->config['app_id'],
95
                'client_secret' => $this->config['app_secret'],
96
                'grant_type'    => $this->config['grant_type'],
97
                'code'          => isset($_REQUEST['code']) ? $_REQUEST['code'] : '',
98
                'redirect_uri'  => $this->config['callback'],
99
            ];
100
            
101
            $response = $this->post($this->AccessTokenURL, $params);
102
            $this->token = $this->parseToken($response);
103
        }
104
    }
105
106
    /**
107
     * 解析access_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('获取Microsoft 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
            $headers = [
126
                'Authorization: Bearer ' . $accessToken,
127
            ];
128
            $data = $this->get($this->UserInfoURL, [], $headers);
129
            $data = json_decode($data, true);
130
            return isset($data['id']);
131
        } catch (\Exception $e) {
132
            return false;
133
        }
134
    }
135
136
    /**
137
     * 刷新AccessToken续期
138
     */
139
    public function refreshToken($refreshToken)
140
    {
141
        $params = [
142
            'client_id'     => $this->config['app_id'],
143
            'client_secret' => $this->config['app_secret'],
144
            'grant_type'    => 'refresh_token',
145
            'refresh_token' => $refreshToken,
146
            'redirect_uri'  => $this->config['callback'],
147
        ];
148
        
149
        $token = $this->post($this->AccessTokenURL, $params);
150
        $token = $this->parseToken($token);
151
        
152
        if (isset($token['access_token'])) {
153
            $this->token = $token;
154
            return true;
155
        }
156
        return false;
157
    }
158
}