如何使用Laravel Socialite实现第三方登录? (微信/GitHub登录)

14次阅读

laravel Socialite 原生支持 gitHub 登录但不支持微信网页授权;github 需严格配置回调 URL 和 scope,微信则须手动实现 OAuth2 三步流程,并注意 state 校验、Token 过期及用户表设计规范。

如何使用Laravel Socialite实现第三方登录? (微信/GitHub登录)

直接说结论:Laravel Socialite 本身不支持微信网页授权登录,但支持 GitHub;微信需手动对接 OAuth2 流程或使用第三方包(如 overtrue/laravel-wechat)。别硬套 Socialite 的 driver 接口去“伪装”微信,会卡在 redirect_uri 域名校验、scope 权限、access_token 换取方式等环节。

GitHub 登录:Socialite 开箱即用,但要注意回调域名和 scope

GitHub 是标准 OAuth2 提供方,Socialite 原生支持。关键不是“怎么写代码”,而是配置是否合规:

  • GitHub Developer Settings 创建 OAuth app 时,Authorization callback URL 必须与你 Laravel 应用中配置的 redirect 完全一致(协议、域名、端口、路径都不能差)
  • config/services.php 中的 github 配置必须包含 client_idclient_secretredirect,且 redirect 要用 url() 动态生成(避免本地开发用 http://localhost 上线后失效)
  • 默认只请求 user:email scope,如果想读用户名或头像,得显式传参:
    return Socialite::driver('github')->scopes(['read:user', 'user:email'])->redirect();
  • GitHub 返回的用户数据里,$user->getName() 可能为空(用户没填 full name),优先用 $user->getNickname()(即 GitHub username)

微信网页登录:不能直接用 Socialite driver,要自己走 OAuth2 三步

微信开放平台的网页授权流程和标准 OAuth2 不完全兼容:它要求先用 code 换取 access_tokenopenid,再用 access_token + openid 拉用户信息——而 Socialite 的 user() 方法期望一步到位返回用户对象。强行适配会导致 token 存储错乱、refresh 失败、无法获取 unionid 等问题。

  • 第一步:构造跳转链接,注意 redirect_uri 必须是微信后台白名单里的地址(且需 urlencode),scopesnsapi_login(获取 openid + 用户基本信息)或 snsapi_userinfo(需用户授权,可得 unionid)
  • 第二步:收到微信回调的 code 后,用 https://api.weixin.qq.com/sns/oauth2/access_token 换取 access_tokenopenid,注意这个接口返回的是 jsON,不是标准 OAuth2 的表单格式
  • 第三步:再调 https://api.weixin.qq.com/sns/userinfo(需带刚拿到的 access_tokenopenid),才能得到昵称、头像等字段;unionid 只有在用户绑定过开放平台账号时才返回
  • 别把 access_token 存进数据库当长期凭证——它 2 小时过期,且微信不提供 refresh 接口;业务层应按需拉取,或用 redis 缓存并设短 TTL

统一用户表设计:别让 provider 字段变成字符串拼接黑洞

很多人把 provider 设为 varchar(20),存 githubwechat_webwechat_mp……结果后期加钉钉、飞书时字段不够用,或查用户时写一 OR。更稳的做法是:

  • providervarchar(16))只存标准化来源名:githubwechat,再加一个 provider_typeenum('web', 'mp', 'app')varchar(10))区分场景
  • provider_id 字段必须是 varchar(64) 或更长——GitHub 的 id 是数字,但微信的 openid 是 28 位字符串,unionid 更长,别用 unsigned big int
  • 首次登录时检查 provider + provider_id 是否已存在;若已存在,直接登录;若不存在,再检查邮箱是否被其他 provider 占用(比如用户先用微信注册,又用 GitHub 同邮箱登录),决定是合并还是报错

最常被忽略的一点:微信网页授权的 state 参数必须你自己生成、存储(session 或 cache)、并在回调时严格比对——Socialite 自动处理的 state 在微信流程里根本不会被识别,漏掉这步就是 csrf 敞开大门。

text=ZqhQzanResources