PC 网站接入微信登录,这 10 个坑我替你踩完了!

产品经理一句"加个微信扫码登录呗",我吭哧吭哧折腾了半天。本以为就是调个官方 API 的事儿,结果不是二维码出不来,就是回调 404,再不就是 Code 换 Token 报错。

今天不整那些虚头巴脑的官方文档复读机,纯干货输出,把内嵌二维码后端换 Token 以及那些官方没明说的潜规则一次性盘明白。

1,先别急着写代码,得拿2个"通行证"

官方文档上来就扔 OAuth2.0 协议,看得人头大。咱们大白话翻译一下:微信登录就是让微信帮你验明正身

在敲键盘之前,先把后勤保障做了(这一步没做,后面全是白干):

  1. 去微信开放平台注册(注意不是公众平台!这俩玩意儿不一样,开放平台是给网站/App用的)。
  2. 创建网站应用并等待审核 。审核通过后,你会拿到两个命根子:
    • AppID:相当于你的"用户名"。
    • AppSecret:相当于你的"密码"。这东西打死不能放前端,泄露了你的应用就裸奔了!
  3. 配置"授权回调域名" :这地方是个大坑!填 www.yourdomain.com 就行,不要带 http://https://,也不要带具体的路径。

2,两种登录方式,选哪个?

官方给了两种玩法,别纠结,按业务场景选:

方式 特点 适用场景
全页面跳转 跳到微信的页面扫码,完事跳回来。 传统老项目,不想折腾样式的。
内嵌二维码(重点) 二维码直接躺在你网站页面上,体验丝滑。 现代 SPA 应用、追求用户体验的。

今天我们主要唠 内嵌二维码,毕竟这玩意看起来更高级(实际上坑也更多)。

3,实战:让二维码在你的页面上"原地出道"

首先,在 HTML 里放一个容器用来放置二维码:

html 复制代码
<div id="wechat-login-box" style="width: 280px; height: 280px;"></div>

然后,引入微信的 JS 并实例化(vue可以在index.html加上):

js 复制代码
<script src="https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>

初始化二维码控件:

html 复制代码
<script>
const wxLogin = new WxLogin({
    // false 就是用户扫完码,页面自动跳转
    self_redirect: false,
    // 容器 ID,必须精确
    id: "wechat-login-box",
    appid: "你的 AppID", 
    // 网页登录只认这个,千万别改!
    scope: "snsapi_login",
    // 注意!必须 URLEncode!
    redirect_uri: encodeURIComponent("https//www.yourdomain.com/callback"), 
    // 防 CSRF 攻击的随机串,强烈建议加!
    state: "123456",
    // 听我的,填 1 用新 UI,好看多了
    stylelite: 1,
    // 默认 1(快速登录),想强制扫码就改成 0
    fast_login: 1,
});
</script>

4,后端拿着 Code 去"换"用户信息

用户扫完码,微信会把浏览器重定向到你指定的 redirect_uri 上,并带上一个 code 参数,像这样: https://www.yourdomain.com/callback?code=071abc123&state=123456

这个 code 值存活 10 分钟,且只能用一次! 拿到它之后,赶紧让后端去微信的接口换 access_token

这里是我的 Node.js (Express) 后端实战代码,注释里全是泪:

javascript 复制代码
const axios = require('axios');
const crypto = require('crypto');

// 前端把 code 传过来
app.get('/api/wx/callback', async (req, res) => {
    const { code, state } = req.query;

    // 坑点预警:这里一定要校验 state!否则容易被 CSRF 攻击
    if (state !== req.session.wxState) {
        return res.send('State 校验失败,你小子是不是想黑我?');
    }

    try {
        // 第一步:用 code + secret 换 access_token
        const tokenUrl = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${APPID}&secret=${APPSECRET}&code=${code}&grant_type=authorization_code`;
        const tokenRes = await axios.get(tokenUrl);
        const { access_token, openid, unionid } = tokenRes.data;

        // 第二步:拿着 access_token 去拿用户头像、昵称
        const userInfoUrl = `https://api.weixin.qq.com/sns/userinfo?access_token=${access_token}&openid=${openid}`;
        const userRes = await axios.get(userInfoUrl);
        
        // 第三步:存 session,返回前端
        req.session.user = {
            nickname: userRes.data.nickname,
            avatar: userRes.data.headimgurl,
            openid: openid,
            unionid: unionid
        };
        
        // 重定向回首页
        res.redirect('/');
    } catch (error) {
        // 坑点预警:如果是 40029,说明 code 过期或被使用了,别重试!
        console.error('微信换 Token 失败了', error.response?.data || error.message);
        res.send('登录超时,请重新扫码');
    }
});

5,踩坑实录

我写代码时在这几个地方卡得怀疑人生,今天全给你抖出来:

坑 1:redirect_uri 的"域名必须完全匹配"玄学

  • 表象:点击登录跳转后微信报错" redirect_uri 域名与后台配置不一致"。
  • 真相 :开放平台配置的是 www.domain.com,你代码里写的是 domain.com少个 www 都不行!端口号也必须一致(80/443 除外)。

坑 2:内嵌二维码的 iframe 跳转问题

  • 表象:用户扫完码,页面没反应,或者打开了新窗口。
  • 真相 :如果你是在弹窗里或者特殊路由下使用,记得把 self_redirect 设为 true。设为 true 时,回调会在 iframe 内跳转,你需要监听 URL 变化自己拿 code,适合单页应用(SPA)的路由拦截。

坑 3:stylelite=1 时,自定义样式(href)直接失效

  • 真相 :官方文档说得很隐晦。我一开始配了 href 想改二维码大小,发现毫无卵用。查阅 FAQ 才发现:开启新 UI(stylelite=1),自定义 CSS 被官方强制覆盖了 。想自定义样式,只能退回 stylelite=0 用旧 UI。

坑 4:快速登录的"坑爹"用户体验

  • 场景:产品经理发现,用户电脑登录着微信,点扫码居然直接一键登录了,连密码都不要,觉得不安全。
  • 解决 :微信 3.9.11+ 默认开启快速登录。如果业务必须要求"本人手机扫码确认",传参时加上 fast_login: 0,强制弹出二维码。

坑 5:一个 Code 只能换一次 Token(巨坑!)

  • 表象 :后端报 {"errcode":40163,"errmsg":"code been used"}
  • 原因:网络波动导致后端请求超时,前端傻傻地重试了一次,结果第二次就把第一次的 Code 给废了。
  • 策略 :拿到 Code 后,后端必须做幂等处理或加锁,一旦换 Token 失败,直接让用户刷新页面重新拿 Code,千万别拿旧 Code 重试!

坑 6:用户拒绝授权咋办?

  • 真相 :如果用户点了"拒绝",微信压根不会跳转回来!前端页面会一直卡在那。
  • 对策 :监听 onQRcodeReady 回调,设置一个定时器。如果 5 分钟内没有收到回调跳转,给用户一个"登录超时,请刷新重试"的按钮。

6,一张图看懂安全流程

为了防止前端同学被后端怼,把这张图甩给他:

text 复制代码
前端页面 -> 展示二维码(用户扫码) 
         -> 微信回调后端(带上 code) 
         -> 后端用 AppSecret + code 请求微信 API(这一步只能后端做!)
         -> 微信返回 access_token + openid
         -> 后端查库 / 注册 / 登录,返回自定义 token
         -> 前端拿到 token,登录成功!

切记 :绝对不要在前端里请求 https://api.weixin.qq.com/sns/oauth2/access_token,因为你的 AppSecret 根本藏不住,浏览器的 Network 面板一眼就能被人抄走!

7,最后说两句

微信登录这东西,文档写得像天书,但捋顺了其实就那么几步。核心就是:域名别配错、Code 别重放、Secret 别见光

如果你按照这个教程走下来还是卡住了,别慌,90% 的锅都在 redirect_uri 的域名匹配上,建议直接去开放平台把那个域名复制出来,跟代码里的逐字比对。

希望兄弟们少掉几根头发,早点下班打游戏!有什么奇葩 Bug 欢迎评论区交流,咱们一起吐槽微信的文档。🤪

本次分享就到这儿啦,我是鹏多多,深耕前端的技术创作者,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~

PS:在本页按F12,在console中输入document.getElementsByClassName('panel-btn')0.click();有惊喜哦~

往期文章

相关推荐
律宏阔1 小时前
微信小程序使用 Orval + OpenAPI 自动生成接口:Axios 兼容踩坑记录
前端·微信小程序
律宏阔1 小时前
微信小程序集成 TDesign 完整记录:解决 NPM packages not found
前端·微信小程序
律宏阔1 小时前
微信小程序 ECharts 瘦身实战:分包异步化 + componentPlaceholder 避开主包 2MB 限制
前端·微信小程序
夏天要喝冰可乐1 小时前
从 Idea 到开源插件:我用 Vibe Coding 做了「文章摆渡」
前端·ai编程·vibecoding
小小小小宇1 小时前
pi agent
前端
风骏时光牛马1 小时前
AI办公能力综合性能专项测试
前端
小小小小宇1 小时前
Pi 手动添加
前端
用户298698530141 小时前
React 中 HTML 内容转 Word 文档的实现方案
javascript·react.js·html
然我1 小时前
模型不是 Agent:从零实现一个最小 Agent Loop
前端·人工智能·agent