| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- <?php
- namespace App\Http\Controllers\Account;
- use App\Cache\WechatStateCache;
- use App\Libs\ApiResponse;
- use App\Services\Account\AccountService;
- use App\Services\Account\WechatService;
- use Illuminate\Http\Request;
- use Illuminate\Routing\Controller as BaseController;
- class WechatController extends BaseController
- {
- use ApiResponse;
- protected $wechatService;
- protected $accountService;
- public function __construct(
- WechatService $wechatService,
- AccountService $accountService
- ) {
- $this->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);
- }
- }
|