ThinkPHP中微信授权登录具体是如何实现的?
- 内容介绍
- 文章标签
- 相关推荐
本文共计892个文字,预计阅读时间需要4分钟。
ThinkPHP+ 没有内置
怎么拼出正确的微信授权跳转 URL
入口控制器里不能靠 config() 直接拼 URL,必须严格 urlencode 所有参数,尤其是 redirect_uri。微信要求它和公众号后台填写的值**完全一致**:协议、域名、端口、路径、结尾斜杠都不能差。
-
scope=snsapi_userinfo才能拿到昵称头像;scope=snsapi_base只拿得到 openid(静默授权) -
state必须是服务端生成并存入 session 的随机字符串,回调时比对,防 CSRF - URL 示例:
"https://open.weixin.qq.com/connect/oauth2/authorize?appid=".config('wechat.app_id')."&redirect_uri=".urlencode('http://localhost:8000/callback/wechat')."&response_type=code&scope=snsapi_userinfo&state=".$_SESSION['wx_state']."#wechat_redirect" - 别漏掉末尾的
#wechat_redirect,否则在微信内打开会白屏
回调里怎么安全换 token 和拉用户信息
收到 code 后必须立刻请求换 token,不能缓存、不能复用、不能跨请求使用 —— code 5 分钟过期且仅能使用一次。
- 换 token 的接口是
https://api.weixin.qq.com/sns/oauth2/access_token,不是管理类 token 接口,返回的access_token仅限网页授权场景 - 调
https://api.weixin.qq.com/sns/userinfo时,access_token和openid必须来自同一轮响应,混用会报{"errcode":40003,"errmsg":"invalid openid"} - 别用
file_get_contents()直接抓,HTTPS 需要处理证书验证;推荐用 ThinkPHP 内置Http::get()并设置verify=false(开发环境)或配好 CA(生产) - 示例关键逻辑:
$res = Http::get("https://api.weixin.qq.com/sns/oauth2/access_token?appid=".config('wechat.app_id')."&secret=".config('wechat.secret')."&code=".$_GET['code']."&grant_type=authorization_code");<br>$tokenData = json_decode($res, true);<br>if (empty($tokenData['access_token'])) { throw new Exception('code invalid or expired'); }<br>$userInfo = Http::get("https://api.weixin.qq.com/sns/userinfo?access_token=".$tokenData['access_token']."&openid=".$tokenData['openid']."&lang=zh_CN");
为什么总遇到 redirect_uri mismatch 错误
这是最常踩的坑,90% 以上是因为配置不一致,而不是代码写错。
立即学习“PHP免费学习笔记(深入)”;
- 公众号后台「网页授权域名」只填域名,不带协议和路径;但跳转时
redirect_uri必须带完整协议+端口+路径,比如http://localhost:8000/callback/wechat - 本地开发用 ngrok 或 xip.io 代理时,后台白名单必须同步更新为当前代理地址
- 如果用了 Nginx 反向代理,确保
$_SERVER['HTTP_HOST']能正确反映外网访问域名,否则urlencode()出来的地址会错 - 测试时用手机微信扫码访问,不要用浏览器直接打开跳转链接 —— 微信会校验 User-Agent 和 Referer
真正麻烦的不是流程本身,而是每个环节都依赖外部配置的一致性:公众号后台、.env、控制器拼接、反向代理规则、HTTPS 证书、session 存储方式 —— 少一个对齐,就卡在某一步不动。调试时优先确认 code 是否能正常到达回调,再查 token 接口返回内容,最后看 userinfo 是否 40003,别一上来就改代码。
本文共计892个文字,预计阅读时间需要4分钟。
ThinkPHP+ 没有内置
怎么拼出正确的微信授权跳转 URL
入口控制器里不能靠 config() 直接拼 URL,必须严格 urlencode 所有参数,尤其是 redirect_uri。微信要求它和公众号后台填写的值**完全一致**:协议、域名、端口、路径、结尾斜杠都不能差。
-
scope=snsapi_userinfo才能拿到昵称头像;scope=snsapi_base只拿得到 openid(静默授权) -
state必须是服务端生成并存入 session 的随机字符串,回调时比对,防 CSRF - URL 示例:
"https://open.weixin.qq.com/connect/oauth2/authorize?appid=".config('wechat.app_id')."&redirect_uri=".urlencode('http://localhost:8000/callback/wechat')."&response_type=code&scope=snsapi_userinfo&state=".$_SESSION['wx_state']."#wechat_redirect" - 别漏掉末尾的
#wechat_redirect,否则在微信内打开会白屏
回调里怎么安全换 token 和拉用户信息
收到 code 后必须立刻请求换 token,不能缓存、不能复用、不能跨请求使用 —— code 5 分钟过期且仅能使用一次。
- 换 token 的接口是
https://api.weixin.qq.com/sns/oauth2/access_token,不是管理类 token 接口,返回的access_token仅限网页授权场景 - 调
https://api.weixin.qq.com/sns/userinfo时,access_token和openid必须来自同一轮响应,混用会报{"errcode":40003,"errmsg":"invalid openid"} - 别用
file_get_contents()直接抓,HTTPS 需要处理证书验证;推荐用 ThinkPHP 内置Http::get()并设置verify=false(开发环境)或配好 CA(生产) - 示例关键逻辑:
$res = Http::get("https://api.weixin.qq.com/sns/oauth2/access_token?appid=".config('wechat.app_id')."&secret=".config('wechat.secret')."&code=".$_GET['code']."&grant_type=authorization_code");<br>$tokenData = json_decode($res, true);<br>if (empty($tokenData['access_token'])) { throw new Exception('code invalid or expired'); }<br>$userInfo = Http::get("https://api.weixin.qq.com/sns/userinfo?access_token=".$tokenData['access_token']."&openid=".$tokenData['openid']."&lang=zh_CN");
为什么总遇到 redirect_uri mismatch 错误
这是最常踩的坑,90% 以上是因为配置不一致,而不是代码写错。
立即学习“PHP免费学习笔记(深入)”;
- 公众号后台「网页授权域名」只填域名,不带协议和路径;但跳转时
redirect_uri必须带完整协议+端口+路径,比如http://localhost:8000/callback/wechat - 本地开发用 ngrok 或 xip.io 代理时,后台白名单必须同步更新为当前代理地址
- 如果用了 Nginx 反向代理,确保
$_SERVER['HTTP_HOST']能正确反映外网访问域名,否则urlencode()出来的地址会错 - 测试时用手机微信扫码访问,不要用浏览器直接打开跳转链接 —— 微信会校验 User-Agent 和 Referer
真正麻烦的不是流程本身,而是每个环节都依赖外部配置的一致性:公众号后台、.env、控制器拼接、反向代理规则、HTTPS 证书、session 存储方式 —— 少一个对齐,就卡在某一步不动。调试时优先确认 code 是否能正常到达回调,再查 token 接口返回内容,最后看 userinfo 是否 40003,别一上来就改代码。

