wechatService = $wechatService; $this->accountService = $accountService; } /** * 微信扫码登录入口:生成 state 后跳转到微信官方二维码页 * * @return \Illuminate\Http\RedirectResponse */ public function login() { $state = md5(uniqid((string)mt_rand(), true)); WechatStateCache::set($state, (int)config('wechat.state_ttl', 600)); return redirect()->away($this->wechatService->buildAuthUrl($state)); } /** * 微信扫码回调:换取用户、注册/登录并带回 token * * @param Request $request * @return \Illuminate\Http\RedirectResponse */ public function callback(Request $request) { $code = trim((string)$request->get('code', '')); $state = trim((string)$request->get('state', '')); $frontend = (string)config('wechat.web.frontend_redirect', '/'); try { if ($state === '' || !WechatStateCache::pull($state)) { throw new \RuntimeException('登录已失效,请重新扫码'); } if ($code === '') { throw new \RuntimeException('未获取到微信授权码'); } list($uid, $isNew) = $this->wechatService->loginByCode($code); $tokenData = $this->accountService->issueTokenForUser((int)$uid); return redirect()->away($this->appendQuery($frontend, [ 'd-token' => $tokenData['token'], 'uid' => (int)$uid, 'is_new' => $isNew ? 1 : 0, ])); } catch (\Throwable $e) { dLog('wechat')->info('wechat callback error', [$e->getMessage()]); return redirect()->away($this->appendQuery($frontend, [ 'wechat_error' => $e->getMessage(), ])); } } /** * 追加 query 参数 * * @param string $url * @param array $params * @return string */ private function appendQuery(string $url, array $params): string { $separator = strpos($url, '?') === false ? '?' : '&'; return $url . $separator . http_build_query($params); } }