love_php/app/Http/Middleware/EasyWechatOAuthMiddleware.php

126 lines
3.7 KiB
PHP
Raw Normal View History

2026-04-02 09:20:51 +08:00
<?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));
}
}