Laravel怎么实现第三方登录_Laravel使用Socialite集成GitHub/QQ【实战】

1次阅读

laravel用socialite集成github或qq登录核心为三步:装包、配配置、写回调;但qq非官方驱动,需额外适配包(如overtrue/laravel-socialite-qq),否则报invalidstateexception或无法获取用户信息。

Laravel怎么实现第三方登录_Laravel使用Socialite集成GitHub/QQ【实战】

直接说结论:Laravel 用 Socialitegithub 或 QQ 登录,核心就三步——装包、配配置、写回调逻辑;但 QQ 登录不是官方驱动,得手动补适配,否则会卡在「InvalidStateException」或拿不到用户信息。

装 Socialite 并确认驱动支持

Socialite 默认只带 GitHub、gitlab、Twitter 等标准 OAuth2 驱动,QQ 是国内特例:它用的是 OAuth 1.0a 协议(老版),且返回字段、签名方式、Token 获取流程都和标准 OAuth2 不兼容。所以:

  • GitHub 登录:直接 composer require laravel/socialite,开箱即用
  • QQ 登录:必须额外装适配包,比如 overtrue/laravel-socialite-qq(注意选 Laravel 版本匹配的分支)
  • Laravel 10+ 用户需确认 socialite 版本 ≥ 5.6,否则不支持 PHP 8.2+ 的某些类型声明

配置 .env 和 config/services.php

GitHub 和 QQ 的配置项命名不同,且 QQ 要求额外填 qq_redirect(不是 redirect):

## .env GITHUB_CLIENT_ID=xxx GITHUB_CLIENT_SECRET=xxx GITHUB_REDIRECT_URI=https://yoursite.com/login/github/callback <p>QQ_APP_ID=xxx QQ_APP_KEY=xxx QQ_REDIRECT_URI=<a href="https://www.php.cn/link/632fb5fbe4d5514c423d7622626e7ee7">https://www.php.cn/link/632fb5fbe4d5514c423d7622626e7ee7</a>

然后在 config/services.php 里对齐:

'github' => [     'client_id' => env('GITHUB_CLIENT_ID'),     'client_secret' => env('GITHUB_CLIENT_SECRET'),     'redirect' => env('GITHUB_REDIRECT_URI'), ], <p>'qq' => [ 'client_id' => env('QQ_APP_ID'), 'client_secret' => env('QQ_APP_KEY'), 'redirect' => env('QQ_REDIRECT_URI'), // 注意:有些 QQ 适配包实际读的是 'qq_redirect' ],

⚠️ 容易踩坑:QQ 开发平台后台填写的「授权回调域」必须和 QQ_REDIRECT_URI 的域名完全一致(不能带 path,也不能是 localhost —— 测试得用 ngrok 或内网穿透)。

路由 + 控制器实现登录跳转与回调

GitHub 可直接用 Socialite::driver('github')->redirect();QQ 必须确保用了正确的 driver 实例(比如 Socialite::driver('qq'),而不是误写成 'qq_oauth'):

// routes/web.php Route::get('/login/github', [LoginController::class, 'redirectToGithub']); Route::get('/login/github/callback', [LoginController::class, 'handleGithubCallback']); <p>Route::get('/login/qq', [LoginController::class, 'redirectToQq']); Route::get('/login/qq/callback', [LoginController::class, 'handleQqCallback']);

控制器里关键点:

  • 跳转前别漏掉 session()->put('state', $socialite->getState())(QQ 适配包通常自动处理,但自定义驱动时容易丢)
  • 回调里必须用 user() 拿数据,不是 stateless()(QQ 不支持无状态模式)
  • GitHub 返回的 $user->getId() 是数字 ID;QQ 返回的 $user->getId()字符串(如 "123456789"),存数据库时字段别设成 unsignedBigInteger

用户绑定与 token 处理的常见断点

拿到第三方用户后,不能直接 Auth::login($user) —— 因为 $userSocialiteUser 实例,不是 Eloquent 模型。典型做法是:

  • User::where('provider_id', $socialiteUser->getId())->where('provider', 'github')->first()
  • 没找到就新建:用 $socialiteUser->getEmail()$socialiteUser->getName() 初始化,但注意 QQ 的 getEmail() 永远返回 NULL(它不开放邮箱),得用 $socialiteUser->getNickname() + 时间戳生成唯一邮箱占位
  • 保存后调用 Auth::login($existingOrNewUser),别忘了 return redirect()->intended('/')

最常被忽略的一点:QQ 登录成功后,$user->token 是临时 access_token,不能长期保存;GitHub 的 token 默认有效期长,但也不建议直接存进数据库明文字段——该用 Laravel Passport 或 Sanctum 做二次 token 化。

text=ZqhQzanResources