ThinkPHP 8.0 实现微信登录需通过微信开放平台网站应用授权(scope=snsapi_login),先配置AppID、AppSecret和HTTPS回调域名,再生成带state校验的授权链接跳转;回调时用code换取access_token与用户信息,依据openid/unionid查找或创建本地用户并完成登录。

ThinkPHP 8.0 实现微信登录,核心是调用微信 OAuth2.0 授权接口获取用户身份,再结合本地用户体系完成登录或绑定。关键不在框架本身有多特殊,而在于正确组织授权流程、安全处理回调、以及合理对接微信开放平台配置。
微信开放平台配置与获取必要参数
必须先在 微信开放平台(不是公众号或小程序后台)注册网站应用,获取以下三项:
-
AppID(即
appid) -
AppSecret(即
appsecret) -
授权回调域名:需填写你线上环境的完整域名(如
https://yourdomain.com),且必须备案、支持 HTTPS;本地开发可暂用 ngrok 或微信开发者工具“网页授权调试”功能绕过校验
注意:公众号网页授权(scope= snsapi_base / snsapi_userinfo)和开放平台网站应用授权(scope= snsapi_login)是两套体系,ThinkPHP 8 登录推荐使用开放平台方式,兼容性更好、无需关注公众号关注状态。
构造微信登录链接并跳转授权
在控制器中生成带签名的授权 URL,重定向到微信:
立即学习“PHP免费学习笔记(深入)”;
// app/controller/Login.php
public function wechat()
{
$redirectUri = urlencode('https://yourdomain.com/login/callback');
$appId = config('wechat.appid');
$url = "https://open.weixin.qq.com/connect/qrconnect?" .
"appid={$appId}" .
"&redirect_uri={$redirectUri}" .
"&response_type=code" .
"&scope=snsapi_login" .
"&state=" . uniqid();
return redirect($url);
}
其中 state 用于防止 CSRF,建议存入 session 并在回调时校验;redirect_uri 必须与开放平台配置的域名一致,且 URL 编码。
接收 code、换取 openid/unionid 并登录用户
微信回调地址(如 /login/callback)收到 code 后,向微信接口请求 access_token 和用户信息:
public function callback(Request $request)
{
$code = $request->get('code');
$state = $request->get('state');
// 校验 state(防止伪造)
if (empty($state) || $state !== session('wechat_state')) {
$this->error('非法请求');
}
// 第一步:用 code 换取 access_token 和 openid
$tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?" .
"appid=" . config('wechat.appid') .
"&secret=" . config('wechat.appsecret') .
"&code={$code}" .
"&grant_type=authorization_code";
$res = json_decode(file_get_contents($tokenUrl), true);
if (isset($res['errcode'])) {
$this->error('微信授权失败:' . $res['errmsg']);
}
// 第二步:拉取用户信息(含 unionid,需用户同意且绑定开放平台账号)
$userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?" .
"access_token={$res['access_token']}" .
"&openid={$res['openid']}";
$user = json_decode(file_get_contents($userInfoUrl), true);
// 此时拿到:$user['openid'], $user['unionid'](如有), $user['nickname'], $user['headimgurl']
// 根据 openid 或 unionid 查找或创建本地用户,然后写入 session 或 JWT 完成登录
$localUser = User::where('wechat_openid', $user['openid'])->find();
if (!$localUser) {
$localUser = User::create([
'nickname' => $user['nickname'],
'avatar' => $user['headimgurl'],
'wechat_openid' => $user['openid'],
'wechat_unionid' => $user['unionid'] ?? null,
]);
}
// 登录逻辑(以 session 为例)
session('user_id', $localUser->id);
return redirect('/home');
}
注意:unionid 仅当用户已在微信开放平台绑定同一主体下的多个应用(如公众号+小程序+网站)时才返回,单网站应用通常只有 openid;若需跨平台识别用户,务必确保所有应用已绑定同一开放平台账号。
安全与体验优化建议
- 所有微信接口调用建议封装成服务类(如
app/service/WeChatService.php),避免控制器臃肿 - 网络请求不要直接用
file_get_contents,推荐用think\Http或GuzzleHttp\Client,支持超时、重试、错误捕获 - 敏感配置(appid/appsecret)统一放在
config/wechat.php,不硬编码 - 用户头像、昵称等字段入库前需过滤 XSS 风险(ThinkPHP 自带
filter验证规则可用) - 首次登录可弹窗引导补全手机号等信息,提升账号安全性
不复杂但容易忽略细节,把授权流程走通、参数对齐、回调校验做好,微信登录在 ThinkPHP 8.0 中就能稳定运行。



















