Completed
Pull Request — master (#33)
by
unknown
05:56 queued 04:14
created

CorpWechatProvider::getTokenUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the overtrue/socialite.
5
 *
6
 * (c) overtrue <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Overtrue\Socialite\Providers;
13
14
use Overtrue\Socialite\AccessToken;
15
use Overtrue\Socialite\AccessTokenInterface;
16
use Overtrue\Socialite\InvalidArgumentException;
17
use Overtrue\Socialite\ProviderInterface;
18
use Overtrue\Socialite\User;
19
20
/**
21
 * Class WeChatProvider.
22
 *
23
 * @link http://mp.weixin.qq.com/wiki/9/01f711493b5a02f24b04365ac5d8fd95.html [WeChat - 公众平台OAuth文档]
24
 * @link https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN [网站应用微信登录开发指南]
25
 */
26
class CorpWechatProvider extends AbstractProvider implements ProviderInterface
27
{
28
    /**
29
     * The base url of WeChat API.
30
     *
31
     * @var string
32
     */
33
    protected $user_baseinfo_api = 'https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo';
34
    protected $user_info_api = 'https://qyapi.weixin.qq.com/cgi-bin/user/get';
35
    protected $access_api_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken';
36
37
    /**
38
     * {@inheritdoc}.
39
     */
40
    protected $openId;
41
42
    /**
43
     * {@inheritdoc}.
44
     */
45
    protected $scopes = ['snsapi_base'];
46
47
    /**
48
     * Indicates if the session state should be utilized.
49
     *
50
     * @var bool
51
     */
52
    protected $stateless = true;
53
54
    /**
55
     * {@inheritdoc}.
56
     */
57
    protected function getAuthUrl($state)
58
    {
59
        $path = 'oauth2/authorize';
60
61
        $url = "https://open.weixin.qq.com/connect/{$path}";
62
        // dd($url);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
63
        return $this->buildAuthUrlFromBase($url, $state);
64
    }
65
66
    /**
67
     * {@inheritdoc}.
68
     */
69
    protected function buildAuthUrlFromBase($url, $state)
70
    {
71
        $query = http_build_query($this->getCodeFields($state), '', '&', $this->encodingType);
72
        $url = $url.'?'.$query.'#wechat_redirect';
73
        return $url;
74
    }
75
76
    /**
77
     * {@inheritdoc}.
78
     */
79 View Code Duplication
    protected function getCodeFields($state = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
80
    {
81
82
        $result = array_merge([
83
            'appid' => $this->clientId,
84
            'redirect_uri' => $this->redirectUrl,
85
            'response_type' => 'code',
86
            'scope' => $this->formatScopes($this->scopes, $this->scopeSeparator),
87
            'state' => $state ?: md5(time()),
88
        ], $this->parameters);
89
90
        return $result;
91
    }
92
93
    /**
94
     * 获取 access token的路径.
95
     */
96
    protected function getTokenUrl()
97
    {
98
        return $this->access_api_url;
99
    }
100
101
    /**
102
     * {@inheritdoc}.
103
     */
104
    protected function getUserByToken(AccessTokenInterface $token)
105
    {
106
107
108
        if (empty($token['UserId'])) {
109
            throw new InvalidArgumentException('UserId of AccessToken is required.');
110
        }
111
112
        $response = $this->getHttpClient()->get($this->user_info_api, [
113
            'query' => [
114
                'access_token' => $token->getToken(),
115
                'userid' => $token['UserId'],
116
            ],
117
        ]);
118
119
        return json_decode($response->getBody(), true);
120
    }
121
122
    /**
123
     * {@inheritdoc}.
124
     */
125
    protected function mapUserToObject(array $user)
126
    {
127
        return new User([
128
            'userid' => $this->arrayItem($user, 'userid'),
129
            'name' => $this->arrayItem($user, 'name'),
130
            'avatar' => $this->arrayItem($user, 'avatar'),
131
            'mobile' => $this->arrayItem($user, 'mobile'),
132
            'department' => $this->arrayItem($user, 'department'),
133
            'gender' => $this->arrayItem($user, 'gender'),
134
            'email' => $this->arrayItem($user, 'email'),
135
            'status' => $this->arrayItem($user, 'status'),
136
        ]);
137
    }
138
139
    /**
140
     * 构建access_token 的参数列表, 分为两种情况一种是 获取access token, 另一种是直接获取userid
141
     */
142
    protected function getTokenFields($code = false)
143
    {
144
        //参数列表: 
145
        // https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=id&corpsecret=secrect
146
147
        if(!$code){
148
            $token_fields = [
149
                'corpid' => $this->clientId,
150
                'corpsecret' => $this->clientSecret,
151
            ];    
152
        }else{
153
            $token_fields = [
154
                'access_token'=>$this->config['longlive_access_token'],
155
                'code'=>$code,
156
            ];    
157
        }
158
     
159
        return $token_fields;
160
    }
161
162
    /**
163
     * 原始微信oauth 应该是返回 access token + openid
164
     * 企业号因为用的是7200秒的, 所以需要支持从外部去获取access_token 不会冲突  要返回 userid 
165
     */
166
    public function getAccessToken($code)
167
    {
168
169
        //没有指定则自己获取
170
        if(!$this->config['longlive_access_token']){
171
            $this->config['longlive_access_token'] = $this->getLongiveAccessToken();
172
        }
173
        $param = $this->getTokenFields($code);
174
        // dd($param);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
175
        $get_token_url = $this->user_baseinfo_api;
176
        $response = $this->getHttpClient()->get($get_token_url, [
177
            'query' => $param,
178
        ]);
179
180
        $content = $response->getBody()->getContents();
181
        $content = json_decode($content,true);
182
        $content['access_token'] =  $this->config['longlive_access_token'];
183
184
        $token = $this->parseAccessToken($content);
185
        return $token;
186
187
    }
188
    // !!应该尽量不要调用, 除非 单独与overture/wechat使用, 否则同时获取accesstoken, 会冲突
189
    public function getLongiveAccessToken($forse_refresh = false){
0 ignored issues
show
Unused Code introduced by
The parameter $forse_refresh is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
190
        $get_token_url = $this->getTokenUrl();
191
        $response = $this->getHttpClient()->get($get_token_url, [
192
            'query' => $this->getTokenFields(),
193
        ]);
194
        $content = $response->getBody()->getContents();
195
        $token = $this->parseAccessToken($content);
196
        return $token['access_token'];
197
    }
198
199
   
200
201
    /**
202
     * Remove the fucking callback parentheses.
203
     *
204
     * @param mixed $response
205
     *
206
     * @return string
207
     */
208
    protected function removeCallback($response)
209
    {
210
        if (strpos($response, 'callback') !== false) {
211
            $lpos = strpos($response, '(');
212
            $rpos = strrpos($response, ')');
213
            $response = substr($response, $lpos + 1, $rpos - $lpos - 1);
214
        }
215
216
        return $response;
217
    }
218
}
219