微信扫码登录(协议详解)
“用微信登录”面向 C 端个人用户:它采用授权码式交互和 scope=snsapi_login,但端点、token、用户字段和错误均为微信私有协议,并非完整标准 OAuth 2.0/OIDC 实现。PC 网站通常展示二维码,用户扫码授权后,浏览器取得一次性 code,再由后端换取用户信息。
标准化边界
本页说明如何兼容平台当前协议,不表示本站建议继续扩展私有实现。新系统应优先要求标准 OIDC/OAuth/SAML/SCIM;必须接入私有流程时,应将它限制在身份网关适配器内。评价基线见统一协议安全评价方法。
面向企业员工的 企业微信扫码登录 使用企业成员标识和应用权限模型,凭据体系不同,不能混用。想直接联调 / 看可点演示,见 Mock 微信(使用)。
本页讲登录落地;微信作为 C 端身份与渠道平台的 API、SDK、ID 作用域和企业适用性见 微信开放平台标准安全评价。
微信登录的几种方式
"用微信登录"按入口不同分四种,底层都是 OAuth2 授权码思路,但发起方式、用户确认方式、换 token / 取用户信息的端点各有差异:
| 方式 | 发起入口 | 用户确认方式 | 换 token 端点 | 拉用户信息 |
|---|---|---|---|---|
| 移动应用(App) | Native iOS/Android SDK(微信 OpenSDK) | 在微信 App 内确认授权 | https://api.weixin.qq.com/sns/oauth2/access_token | https://api.weixin.qq.com/sns/userinfo |
| 网站应用(PC) | https://open.weixin.qq.com/connect/qrconnect | 用微信 App 扫二维码 | https://api.weixin.qq.com/sns/oauth2/access_token | https://api.weixin.qq.com/sns/userinfo |
| 小程序 | 小程序 SDK wx.login | 无需用户显式授权(静默拿 code) | https://api.weixin.qq.com/sns/jscode2session | 随 jscode2session 返回(openid/session_key) |
| 公众号网页授权 | https://open.weixin.qq.com/connect/oauth2/authorize | 在微信 App 内确认授权 | https://api.weixin.qq.com/sns/oauth2/access_token | https://api.weixin.qq.com/sns/userinfo |
怎么选
- PC 网站登录 → 网站应用(扫码),即本页下文详解的流程。
- 自己的 iOS/Android App 里用微信登录 → 移动应用(App),见下节。
- 微信内的公众号 H5 页面 → 公众号网页授权。
- 微信小程序内 →
wx.login+jscode2session。
移动应用、网站应用、公众号三者后端流程一致(/sns/oauth2/access_token 换 access_token+openid,再 /sns/userinfo 拉资料),区别只在前端如何发起、如何让用户确认、如何拿到 code。小程序是另一套(见下)。
移动应用(App)登录
在你自己的 iOS / Android App 里用微信登录,走微信 OpenSDK,是 App 间跳转而非扫码:
要点:
- 需在微信开放平台注册移动应用,配置 iOS 的
Bundle ID(及 Universal Link)/ Android 的包名 + 应用签名,否则拉起微信授权会失败。 - App 端集成 OpenSDK 后用
SendAuth.Req发起授权(scope=snsapi_userinfo),用户在微信内确认,微信通过onResp回调把一次性code交回你的 App。 - 拿到
code之后与网站应用完全一样:App 把code交给你的后端,后端用AppID+AppSecret+code调/sns/oauth2/access_token换access_token+openid,再调/sns/userinfo拉资料。AppSecret只在后端。 - 移动应用不涉及二维码、也不涉及
wxLogin.js;下文关于 JS SDK 的内容仅适用于网站应用。
小程序 / 公众号(简述)
- 小程序:前端
wx.login()静默取得临时code,后端用AppID+AppSecret+js_code调/sns/jscode2session换取openid+session_key(满足平台条件时可能返回unionid)。它不使用/sns/userinfo;头像、昵称、手机号等资料必须按当前小程序接口和用户授权规则另行获取。 - 公众号网页授权:微信内 H5 跳
/connect/oauth2/authorize——scope=snsapi_base静默只拿openid,scope=snsapi_userinfo需用户在微信内确认、可拿完整资料。后端换 token / 拉资料端点与网站应用相同。
下文以 网站应用(PC 扫码) 为主线详解落地。
整体流程
code 在浏览器里拿到,换 token 与拉资料都在后端完成(需要 AppSecret)。
JS SDK(wxLogin.js)到底在干什么
wxLogin.js 是一段很薄的浏览器脚本。你给它 appid、scope、redirect_uri、state 等,它在你指定的容器 <div> 里:
- 拼出官方授权 URL 并插入一个
<iframe>指向微信官方扫码页(open.weixin.qq.com/connect/qrconnect)——二维码是微信域下的页面,渲染、扫码状态、过期刷新都由官方页处理; - 把
code交回你的页面:用户扫码确认后,官方页带着code+state跳转到你的redirect_uri; self_redirect控制在哪跳:false= 顶层窗口跳转(整页到redirect_uri),true= 在 iframe 内跳转;- 顺带处理 iframe 尺寸/样式、Chrome 142+ 的
allow="local-network-access"等。
一句话:SDK = "把官方二维码嵌进你的页面 + 把扫码得到的 code 送回来"。它不接触 AppSecret,也不参与后端换 token。
为什么要用 JS SDK(而不是自己拼链接)
也可以不用 SDK——直接整页跳转到 https://open.weixin.qq.com/connect/qrconnect?...#wechat_redirect,扫完回跳。但用 SDK 内嵌二维码:
- 不跳出站点:用户停在你的登录页,不被带到微信域再跳回,体验连续、转化更高;
- 回避跨域:二维码页在微信域、你的页面在你自己域。自己写 iframe 要处理扫码状态轮询、跨域拿
code、样式适配;SDK 用官方页完成这些,扫码成功后由官方页顶层跳转把code交回,你不用碰跨域通信; - 官方维护、协议对齐:微信改版(快捷登录、样式参数、Chrome 兼容)由 SDK 跟进。
若你就是想整页跳转 / 后端渲染,也可以不用 SDK;拿到
code之后的后端流程完全一样。
拿到 code 之后
微信"网站应用"取用户只要两步(比企业微信少):
/sns/oauth2/access_token:用AppID+AppSecret+code换access_token+openid(以及接口在满足条件时返回的unionid、refresh_token等字段)。这里的access_token与该用户授权绑定,不同于企业微信的应用级 token。/sns/userinfo:用access_token+openid拉昵称、头像等资料。
关键概念
openid:用户在该应用内的唯一标识;换个应用同一个人openid不同。unionid:在应用归属、开放平台绑定等条件满足时,可用于关联同一开放平台主体下的用户。它并非每个入口、每次响应都必然返回;数据库应保留(appid, openid)原始键,并在实际取得unionid后建立关联。scope=snsapi_login:网站应用扫码登录固定用它。- 授权回调域:开放平台后台配置(只填域名);与
redirect_uri域名不一致会报错。 state:防 CSRF。- 快捷登录:较新桌面微信(Windows 3.9.11+ / Mac 4.0+)已登录时会提示免扫码确认,用户仍可切二维码。
注意:当前微信网站登录未提供 PKCE。这是相对 OAuth 2.0 Security BCP 的安全与标准化差距;“code 仅在后端配合 AppSecret 交换”是现有补偿控制,不能替代 PKCE 对授权码截获的防护。
安全要点
code换 token 一律在后端,AppSecret绝不进前端或仓库;- 校验
state,防 CSRF; - 强制 HTTPS,正确配置授权回调域;
code短时效、应视为一次性;access_token有有效期,注意刷新。
动手 / 联调
- 🔬 扫码登录演示 —— 用 Mock 同款 SDK 真实可点跑通扫码登录(切到「微信」标签)
- 🧪 Mock 微信(使用) —— 端点、接入代码与"上线只改 JS 与 URL"
- 📖 OAuth 2.0 文档 · 企业微信扫码登录 对比