ThinkPHP中微信授权登录具体是如何实现的?

2026-04-28 23:063阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计892个文字,预计阅读时间需要4分钟。

ThinkPHP中微信授权登录具体是如何实现的?

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_tokenopenid 必须来自同一轮响应,混用会报 {"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中微信授权登录具体是如何实现的?

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_tokenopenid 必须来自同一轮响应,混用会报 {"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,别一上来就改代码。