126 lines
3.7 KiB
PHP
126 lines
3.7 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Http\Middleware;
|
||
|
|
|
||
|
|
use App\Models\Server\MerchantUser;
|
||
|
|
use Closure;
|
||
|
|
use http\Env\Request;
|
||
|
|
use Illuminate\Support\Arr;
|
||
|
|
use Illuminate\Support\Facades\Log;
|
||
|
|
use Illuminate\Support\Facades\Redis;
|
||
|
|
use Illuminate\Support\Str;
|
||
|
|
use Overtrue\LaravelWeChat\Events\WeChatUserAuthorized;
|
||
|
|
|
||
|
|
class EasyWechatOAuthMiddleware
|
||
|
|
{
|
||
|
|
|
||
|
|
private $cacheKey = "saas:wechat:oauth:%s";
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Handle an incoming request.
|
||
|
|
*
|
||
|
|
* @param \Illuminate\Http\Request $request
|
||
|
|
* @param \Closure $next
|
||
|
|
* @param string|null $scopes
|
||
|
|
* @return mixed
|
||
|
|
*/
|
||
|
|
public function handle($request, Closure $next, $account = 'default', $scopes = null)
|
||
|
|
{
|
||
|
|
Log::info("EasyWechatOAuthMiddleware");
|
||
|
|
// $account 与 $scopes 写反的情况
|
||
|
|
if (is_array($scopes) || (\is_string($account) && Str::is('snsapi_*', $account))) {
|
||
|
|
list($account, $scopes) = [$scopes, $account];
|
||
|
|
$account || $account = 'default';
|
||
|
|
}
|
||
|
|
|
||
|
|
$isNewSession = false;
|
||
|
|
$sessionKey = \sprintf('wechat.oauth_user.%s', $account);
|
||
|
|
$config = config(\sprintf('wechat.official_account.%s', $account), []);
|
||
|
|
$officialAccount = app(\sprintf('wechat.official_account.%s', $account));
|
||
|
|
$scopes = $scopes ?: Arr::get($config, 'oauth.scopes', ['snsapi_base']);
|
||
|
|
|
||
|
|
if (is_string($scopes)) {
|
||
|
|
$scopes = array_map('trim', explode(',', $scopes));
|
||
|
|
}
|
||
|
|
|
||
|
|
$session = session($sessionKey, []);
|
||
|
|
$isAuth = false;
|
||
|
|
if ($session) {
|
||
|
|
$openid = $session->getId() ?? '';
|
||
|
|
$isAuth = Redis::get(printf($this->cacheKey, $openid));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$session || !$isAuth) {
|
||
|
|
if ($request->has('code')) {
|
||
|
|
$user = $officialAccount->oauth->user() ?? [];
|
||
|
|
//更新用户数据
|
||
|
|
$this->saveUser($user);
|
||
|
|
|
||
|
|
session([$sessionKey => $user]);
|
||
|
|
$isNewSession = true;
|
||
|
|
|
||
|
|
event(new WeChatUserAuthorized(session($sessionKey), $isNewSession, $account));
|
||
|
|
|
||
|
|
return redirect()->to($this->getTargetUrl($request));
|
||
|
|
}
|
||
|
|
|
||
|
|
session()->forget($sessionKey);
|
||
|
|
|
||
|
|
return $officialAccount->oauth->scopes($scopes)->redirect($request->fullUrl());
|
||
|
|
}
|
||
|
|
|
||
|
|
event(new WeChatUserAuthorized(session($sessionKey), $isNewSession, $account));
|
||
|
|
|
||
|
|
return $next($request);
|
||
|
|
}
|
||
|
|
|
||
|
|
private function saveUser($user)
|
||
|
|
{
|
||
|
|
if (!$user) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
$user = $user->getOriginal();
|
||
|
|
Log::info($user);
|
||
|
|
$openid = $user['openid'] ?? '';
|
||
|
|
$nickname = $user['nickname'] ?? '';
|
||
|
|
$pic = $user['headimgurl'] ?? '';
|
||
|
|
$unionid = $user['unionid'] ?? '';
|
||
|
|
|
||
|
|
if (!($openid && strlen($nickname) > 0 && $pic && $unionid)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$merchant_user = MerchantUser::where('openid', $openid)->first();
|
||
|
|
if (!$merchant_user) {
|
||
|
|
$merchant_user = new MerchantUser;
|
||
|
|
$merchant_user->openid = $openid;
|
||
|
|
}
|
||
|
|
$merchant_user->nickname = $nickname;
|
||
|
|
$merchant_user->pic = $pic;
|
||
|
|
$merchant_user->authorize_at = date('Y-m-d H:i:s');
|
||
|
|
|
||
|
|
$has = MerchantUser::where('unionid', $unionid)->count();
|
||
|
|
if (!$has) {
|
||
|
|
$merchant_user->unionid = $unionid;
|
||
|
|
}
|
||
|
|
|
||
|
|
$merchant_user->save();
|
||
|
|
Redis::setex(printf($this->cacheKey, $openid), 60, 1);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Build the target business url.
|
||
|
|
*
|
||
|
|
* @param Request $request
|
||
|
|
*
|
||
|
|
* @return string
|
||
|
|
*/
|
||
|
|
protected function getTargetUrl($request)
|
||
|
|
{
|
||
|
|
$queries = Arr::except($request->query(), ['code', 'state']);
|
||
|
|
|
||
|
|
return $request->url() . (empty($queries) ? '' : '?' . http_build_query($queries));
|
||
|
|
}
|
||
|
|
}
|