OAuthAuthenticate::handle()   D
last analyzed

Complexity

Conditions 9
Paths 16

Size

Total Lines 43
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 43
rs 4.909
c 0
b 0
f 0
cc 9
eloc 24
nc 16
nop 3
1
<?php
2
3
namespace Freyo\LaravelEntWechat\Middleware;
4
5
use Closure;
6
use EntWeChat\Foundation\Application;
7
use Event;
8
use Freyo\LaravelEntWechat\Events\WeChatUserAuthorized;
9
use Log;
10
11
/**
12
 * Class OAuthAuthenticate.
13
 */
14
class OAuthAuthenticate
15
{
16
    /**
17
     * Use Service Container would be much artisan.
18
     */
19
    private $wechat;
20
21
    /**
22
     * Inject the wechat service.
23
     */
24
    public function __construct(Application $wechat)
25
    {
26
        $this->wechat = $wechat;
27
    }
28
29
    /**
30
     * Handle an incoming request.
31
     *
32
     * @param \Illuminate\Http\Request $request
33
     * @param \Closure                 $next
34
     * @param string|null              $account
35
     *
36
     * @return mixed
37
     */
38
    public function handle($request, Closure $next, $account = null)
39
    {
40
        $isNewSession = false;
41
        $onlyRedirectInWeChatBrowser = config('entwechat.oauth.only_wechat_browser', false);
42
        $scopes = config('entwechat.oauth.scopes', ['snsapi_base']);
43
44
        if (!is_null($account)) {
45
            $this->wechat = $this->wechat->account($account);
46
            $onlyRedirectInWeChatBrowser = config("entwechat.account.{$account}.oauth.only_wechat_browser", false);
47
            $scopes = config("entwechat.account.{$account}.oauth.scopes", ['snsapi_base']);
48
        }
49
50
        if ($onlyRedirectInWeChatBrowser && !$this->isWeChatBrowser($request)) {
51
            if (config('debug')) {
52
                Log::debug('[not wechat browser] skip wechat oauth redirect.');
53
            }
54
55
            return $next($request);
56
        }
57
58
        if (is_string($scopes)) {
59
            $scopes = array_map('trim', explode(',', $scopes));
60
        }
61
62
        if (!session('entwechat.oauth_user') || $this->needReauth($scopes)) {
63
            if ($request->has('code')) {
64
                session(['entwechat.oauth_user' => $this->wechat->oauth->user()]);
65
                $isNewSession = true;
66
67
                Event::fire(new WeChatUserAuthorized(session('entwechat.oauth_user'), $isNewSession));
68
69
                return redirect()->to($this->getTargetUrl($request));
70
            }
71
72
            session()->forget('entwechat.oauth_user');
73
74
            return $this->wechat->oauth->scopes($scopes)->redirect($request->fullUrl());
75
        }
76
77
        Event::fire(new WeChatUserAuthorized(session('entwechat.oauth_user'), $isNewSession));
78
79
        return $next($request);
80
    }
81
82
    /**
83
     * Build the target business url.
84
     *
85
     * @param Request $request
86
     *
87
     * @return string
88
     */
89
    protected function getTargetUrl($request)
90
    {
91
        $queries = array_except($request->query(), ['code', 'state']);
92
93
        return $request->url().(empty($queries) ? '' : '?'.http_build_query($queries));
94
    }
95
96
    /**
97
     * Is different scopes.
98
     *
99
     * @param array $scopes
100
     *
101
     * @return bool
102
     */
103
    protected function needReauth($scopes)
104
    {
105
        return session('entwechat.oauth_user.original.scope') == 'snsapi_base' && in_array('snsapi_userinfo', $scopes);
106
    }
107
108
    /**
109
     * Detect current user agent type.
110
     *
111
     * @param \Illuminate\Http\Request $request
112
     *
113
     * @return bool
114
     */
115
    protected function isWeChatBrowser($request)
116
    {
117
        return strpos($request->header('user_agent'), 'MicroMessenger') !== false;
118
    }
119
}
120