Skip to content

Commit 7bb0212

Browse files
committed
Update.
1 parent acd348c commit 7bb0212

File tree

5 files changed

+90
-117
lines changed

5 files changed

+90
-117
lines changed

README.md

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,65 @@ Route::group(['middleware' => ['web', 'wechat.oauth']], function () {
163163
});
164164
```
165165

166-
当然,你也可以在中间件参数指定当前的 `scopes`:
166+
中间件支持指定配置名称:`'wechat.oauth:default'`当然,你也可以在中间件参数指定当前的 `scopes`:
167167

168168
```php
169-
Route::group(['middleware' => ['web', 'wechat.oauth:snsapi_userinfo']], function () {
169+
Route::group(['middleware' => ['wechat.oauth:snsapi_userinfo']], function () {
170170
// ...
171171
});
172+
173+
// 或者指定账户的同时指定 scopes:
174+
Route::group(['middleware' => ['wechat.oauth:default,snsapi_userinfo']], function () {
175+
// ...
176+
});
177+
```
178+
179+
上面的路由定义了 `/user` 是需要微信授权的,那么在这条路由的**回调 或 控制器对应的方法里**, 你就可以从 `session('wechat.oauth_user.default')` 拿到已经授权的用户信息了。
180+
181+
## 模拟授权
182+
183+
有时候我们希望在本地开发完成后线上才真实的走微信授权流程,这将减少我们的开发成本,那么你需要做以下两步:
184+
185+
1. 准备假资料:
186+
187+
> 以下字段在 scope 为 `snsapi_userinfo` 时尽可能配置齐全哦,当然,如果你的模式只是 `snsapi_base` 的话只需要 `openid` 就好了。
188+
189+
```php
190+
use Overtrue\Socialite\User as SocialiteUser;
191+
192+
$user = new SocialiteUser([
193+
'id' => array_get($user, 'openid'),
194+
'name' => array_get($user, 'nickname'),
195+
'nickname' => array_get($user, 'nickname'),
196+
'avatar' => array_get($user, 'headimgurl'),
197+
'email' => null,
198+
'original' => [],
199+
'provider' => 'WeChat',
200+
]);
201+
202+
```
203+
204+
2. 将资料写入 session:
205+
206+
> 注意:一定要在 OAuth 中间件之前写入,比如你可以创建一个全局中间件来完成这件事儿,当然了,只在开发环境启用即可。
207+
208+
```php
209+
session(['wechat.oauth_user.default' => $user]); // 同理,`default` 可以更换为您对应的其它配置名
210+
```
211+
212+
## 事件
213+
214+
> 你可以监听相应的事件,并对事件发生后执行相应的操作。
215+
216+
- OAuth 网页授权:`Overtrue\LaravelWeChat\Events\WeChatUserAuthorized`
217+
218+
```php
219+
// 该事件有以下属性
220+
$event->user; // 同 session('wechat.oauth_user.default') 一样
221+
$event->isNewSession; // 是不是新的会话(第一次创建 session 时为 true)
222+
$event->account; // 当前中间件所使用的账号,对应在配置文件中的配置项名称
172223
```
173224

174-
上面的路由定义了 `/user` 是需要微信授权的,那么在这条路由的**回调 或 控制器对应的方法里**, 你就可以从 `session('wechat.oauth_user')` 拿到已经授权的用户信息了。
175225

176226
## 开放平台路由支持
177227

@@ -202,45 +252,7 @@ $message = $event->payload; // 开放平台事件通知内容
202252

203253
配置后 `http://example.com/open-platform/serve` 则为开放平台第三方应用设置的授权事件接收 URL。
204254

205-
## 模拟授权
206-
207-
有时候我们希望在本地开发完成后线上才真实的走微信授权流程,这将减少我们的开发成本,那么你需要做以下两步:
208-
209-
1. 在 config/wechat.php 中将:'enable_mock' 启用,不论你是用 `.env` 文件里 `WECHAT_ENABLE_MOCK=true` 或者其它什么方法都可以。
210-
2. 在 config/wechat.php 中配置 `mock_user` 为微信的模拟的用户资料:
211255

212-
```php
213-
/*
214-
* 开发模式下的免授权模拟授权用户资料
215-
*
216-
* 当 enable_mock 为 true 则会启用模拟微信授权,用于开发时使用,开发完成请删除或者改为 false 即可
217-
*/
218-
'enable_mock' => env('WECHAT_ENABLE_MOCK', true),
219-
'mock_user' => [
220-
'openid' => 'odh7zsgI75iT8FRh0fGlSojc9PWM',
221-
// 以下字段为 scope 为 snsapi_userinfo 时需要
222-
'nickname' => 'overtrue',
223-
'sex' => '1',
224-
'province' => '北京',
225-
'city' => '北京',
226-
'country' => '中国',
227-
'headimgurl' => 'http://wx.qlogo.cn/mmopen/C2rEUskXQiblFYMUl9O0G05Q6pKibg7V1WpHX6CIQaic824apriabJw4r6EWxziaSt5BATrlbx1GVzwW2qjUCqtYpDvIJLjKgP1ug/0',
228-
],
229-
```
230-
231-
以上字段在 scope 为 `snsapi_userinfo` 时尽可能配置齐全哦,当然,如果你的模式只是 `snsapi_base` 的话只需要 `openid` 就好了。
232-
233-
## 事件
234-
235-
> 你可以监听相应的事件,并对事件发生后执行相应的操作。
236-
237-
- OAuth 网页授权:`Overtrue\LaravelWeChat\Events\WeChatUserAuthorized`
238-
239-
```php
240-
// 该事件有两个属性
241-
$event->user; // 同 session('wechat.oauth_user') 一样
242-
$event->isNewSession; // 是不是新的会话(第一次创建 session 时为 true)
243-
```
244256

245257
更多 SDK 的具体使用请参考:https://easywechat.com
246258

src/Events/WeChatUserAuthorized.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@ class WeChatUserAuthorized
2222

2323
public $isNewSession;
2424

25+
public $account;
26+
2527
/**
2628
* Create a new event instance.
2729
*
2830
* @param \Overtrue\Socialite\User $user
2931
* @param bool $isNewSession
3032
*/
31-
public function __construct(User $user, $isNewSession = false)
33+
public function __construct(User $user, $isNewSession = false, string $account)
3234
{
3335
$this->user = $user;
3436
$this->isNewSession = $isNewSession;
37+
$this->account = $account;
3538
}
3639

3740
/**
@@ -44,6 +47,16 @@ public function getUser()
4447
return $this->user;
4548
}
4649

50+
/**
51+
* The name of official account.
52+
*
53+
* @return string
54+
*/
55+
public function getAccount()
56+
{
57+
return $this->account;
58+
}
59+
4760
/**
4861
* Check the user session is first created.
4962
*

src/Middleware/OAuthAuthenticate.php

Lines changed: 21 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,16 @@
1212
namespace Overtrue\LaravelWeChat\Middleware;
1313

1414
use Closure;
15-
use EasyWeChat\OfficialAccount\Application;
1615
use Event;
17-
use Log;
16+
use http\Env\Request;
1817
use Overtrue\LaravelWeChat\Events\WeChatUserAuthorized;
18+
use Overtrue\Socialite\User;
1919

2020
/**
2121
* Class OAuthAuthenticate.
2222
*/
2323
class OAuthAuthenticate
2424
{
25-
/**
26-
* Use Service Container would be much artisan.
27-
*/
28-
private $wechat;
29-
30-
/**
31-
* Inject the wechat service.
32-
*
33-
* @param \EasyWeChat\OfficialAccount\Application $wechat
34-
*/
35-
public function __construct(Application $wechat)
36-
{
37-
$this->wechat = $wechat;
38-
}
39-
4025
/**
4126
* Handle an incoming request.
4227
*
@@ -46,41 +31,42 @@ public function __construct(Application $wechat)
4631
*
4732
* @return mixed
4833
*/
49-
public function handle($request, Closure $next, $scopes = null)
34+
public function handle($request, Closure $next, $account = 'default', $scopes = null)
5035
{
51-
$isNewSession = false;
52-
$onlyRedirectInWeChatBrowser = config('wechat.official_account.oauth.only_wechat_browser', false);
53-
54-
if ($onlyRedirectInWeChatBrowser && !$this->isWeChatBrowser($request)) {
55-
if (config('wechat.debug')) {
56-
Log::debug('[not wechat browser] skip wechat oauth redirect.');
57-
}
58-
59-
return $next($request);
36+
// $account 与 $scopes 写反的情况
37+
if (is_array($scopes) || (\is_string($account) && str_is($account, 'snsapi_*'))) {
38+
list($account, $scopes) = [$scopes, $account];
39+
$account || $account = 'default';
6040
}
6141

62-
$scopes = $scopes ?: config('wechat.official_account.oauth.scopes', ['snsapi_base']);
42+
$isNewSession = false;
43+
$sessionKey = \sprintf('wechat.oauth_user.%s', $account);
44+
$config = config(\sprintf('wechat.official_account.%s', $account), []);
45+
$officialAccount = app(\sprintf('wechat.official_account.%s', $account));
46+
$scopes = $scopes ?: array_get($config, 'oauth.scopes', ['snsapi_base']);
6347

6448
if (is_string($scopes)) {
6549
$scopes = array_map('trim', explode(',', $scopes));
6650
}
6751

68-
if (!session('wechat.oauth_user') || $this->needReauth($scopes)) {
52+
$session = session($sessionKey, []);
53+
54+
if (!$session) {
6955
if ($request->has('code')) {
70-
session(['wechat.oauth_user' => $this->wechat->oauth->user()]);
56+
session([$sessionKey => $officialAccount->oauth->user() ?? []]);
7157
$isNewSession = true;
7258

73-
Event::fire(new WeChatUserAuthorized(session('wechat.oauth_user'), $isNewSession));
59+
Event::fire(new WeChatUserAuthorized(session($sessionKey), $isNewSession, $account));
7460

7561
return redirect()->to($this->getTargetUrl($request));
7662
}
7763

78-
session()->forget('wechat.oauth_user');
64+
session()->forget($sessionKey);
7965

80-
return $this->wechat->oauth->scopes($scopes)->redirect($request->fullUrl());
66+
return $officialAccount->oauth->scopes($scopes)->redirect($request->fullUrl());
8167
}
8268

83-
Event::fire(new WeChatUserAuthorized(session('wechat.oauth_user'), $isNewSession));
69+
Event::fire(new WeChatUserAuthorized(session($sessionKey), $isNewSession, $account));
8470

8571
return $next($request);
8672
}
@@ -99,18 +85,6 @@ protected function getTargetUrl($request)
9985
return $request->url().(empty($queries) ? '' : '?'.http_build_query($queries));
10086
}
10187

102-
/**
103-
* Is different scopes.
104-
*
105-
* @param array $scopes
106-
*
107-
* @return bool
108-
*/
109-
protected function needReauth($scopes)
110-
{
111-
return 'snsapi_base' == session('wechat.oauth_user.original.scope') && in_array('snsapi_userinfo', $scopes);
112-
}
113-
11488
/**
11589
* Detect current user agent type.
11690
*
@@ -120,6 +94,6 @@ protected function needReauth($scopes)
12094
*/
12195
protected function isWeChatBrowser($request)
12296
{
123-
return false !== strpos($request->header('user_agent'), 'MicroMessenger');
97+
return false !== strpos($request->header('user_agent', ''), 'MicroMessenger');
12498
}
12599
}

src/ServiceProvider.php

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use Illuminate\Foundation\Application as LaravelApplication;
2020
use Illuminate\Support\ServiceProvider as LaravelServiceProvider;
2121
use Laravel\Lumen\Application as LumenApplication;
22-
use Overtrue\Socialite\User as SocialiteUser;
2322

2423
/**
2524
* Class ServiceProvider.
@@ -33,10 +32,6 @@ class ServiceProvider extends LaravelServiceProvider
3332
*/
3433
public function boot()
3534
{
36-
if ($this->app instanceof LaravelApplication) {
37-
// 创建模拟授权
38-
$this->setUpMockAuthUser();
39-
}
4035
}
4136

4237
/**
@@ -47,7 +42,7 @@ protected function setupConfig()
4742
$source = realpath(__DIR__.'/config.php');
4843

4944
if ($this->app instanceof LaravelApplication && $this->app->runningInConsole()) {
50-
$this->publishes([$source => config_path('wechat.php')]);
45+
$this->publishes([$source => config_path('wechat.php')], 'laravel-wechat');
5146
} elseif ($this->app instanceof LumenApplication) {
5247
$this->app->configure('wechat');
5348
}
@@ -85,6 +80,7 @@ public function register()
8580
$accounts = [
8681
'default' => config('wechat.'.$name),
8782
];
83+
config(['wechat.'.$name.'.default' => $accounts]);
8884
} else {
8985
$accounts = config('wechat.'.$name);
9086
}
@@ -116,24 +112,4 @@ protected function getRouter()
116112

117113
return $this->app->router;
118114
}
119-
120-
/**
121-
* 创建模拟登录.
122-
*/
123-
protected function setUpMockAuthUser()
124-
{
125-
$user = config('wechat.mock_user');
126-
127-
if (is_array($user) && !empty($user['openid']) && config('wechat.enable_mock')) {
128-
$user = (new SocialiteUser([
129-
'id' => array_get($user, 'openid'),
130-
'name' => array_get($user, 'nickname'),
131-
'nickname' => array_get($user, 'nickname'),
132-
'avatar' => array_get($user, 'headimgurl'),
133-
'email' => null,
134-
]))->merge(['original' => array_merge($user, ['privilege' => []])])->setProviderName('WeChat');
135-
136-
session(['wechat.oauth_user' => $user]);
137-
}
138-
}
139115
}

src/config.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,10 @@
7474
/*
7575
* OAuth 配置
7676
*
77-
* only_wechat_browser: 只在微信浏览器跳转
7877
* scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
7978
* callback:OAuth授权完成后的回调页地址(如果使用中间件,则随便填写。。。)
8079
*/
8180
// 'oauth' => [
82-
// 'only_wechat_browser' => false,
8381
// 'scopes' => array_map('trim', explode(',', env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_SCOPES', 'snsapi_userinfo'))),
8482
// 'callback' => env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_CALLBACK', '/examples/oauth_callback.php'),
8583
// ],

0 commit comments

Comments
 (0)