H5端通过生成唯一loginId并渲染二维码供手机扫描,自身轮询服务端状态;App端调用uni.scanCode扫码后提交loginId与用户信息至服务端绑定;服务端统一协调,基于Redis实现过期控制与原子更新,确保登录安全可靠。
uni-app实现扫码登录时,网页端(H5)和 App 端无法直接“联动”——它们是完全独立的运行环境,没有共享进程、内存或会话。所谓“联动”,本质是服务端统一协调 + 前端各自完成扫码/被扫角色切换。
网页端(H5)怎么发起扫码登录?
H5 不能调用
,也不支持摄像头直扫,必须走「图片识别」路径:
用户点击“扫码登录”,前端生成一个唯一
(如 UUID),拼到后端授权地址里,例如
后端返回该 URL 的二维码图片 base64 或可访问链接,H5 页面用
渲染
用户用手机微信/其他 App 扫这个码,跳转到后端回调页,携带
和用户身份信息(如 openid)
H5 页面轮询
,直到后端返回登录成功状态
注意:
+
解析本地图片的方式仅适用于「用户手动上传截图」,不是标准扫码登录流程,容易被误点、延迟高、体验差,不推荐用于正式场景。
App 端怎么作为“扫码器”参与登录?
App 端角色是“主动扫码方”,要调起摄像头扫描网页端展示的二维码:
App 端使用
(推荐)或原生插件(如
鸿蒙、
)获取扫码结果
扫码结果通常是字符串,需解析出其中的
(比如 URL 中的 query 参数)
App 端立即 POST
到后端绑定接口,后端完成会话建立并通知 H5 页面
不要在 App 端尝试跳转 H5 页面或操作其 DOM —— 它们跨域且无上下文
常见错误:App 扫完码后试图用
跳转到 H5 的某个页面,这毫无意义。H5 页面必须自己轮询或监听 WebSocket 通知来刷新登录态。
uni-app电商系统实战精讲课程课件
uni-app电商系统实战精讲课程
下载
服务端必须承担的核心协调逻辑
这是整个流程成败的关键,前端只是执行者:
为每次扫码请求生成带过期时间(如 3 分钟)的
,存入 Redis:
App 提交扫码结果后,更新为
并写入用户标识
H5 轮询接口需校验 Redis 中该
是否存在且未过期,返回
后清空记录
若超时未扫,Redis 自动过期,H5 轮询返回
,前端提示重试
漏掉过期机制或未做原子更新(如用 GET+SET 而非 Redis Lua 脚本),会导致重复登录、状态错乱、安全漏洞。
为什么不能用 localStorage / Cookie / broadcastChannel 联动?
因为 H5 和 App 是两个隔离环境:
H5 运行在浏览器中,受同源策略限制,无法读取 App 内 WebView 的
App 打包的 WebView 默认不共享 Cookie,即使同域名也无法自动透传 session
只在同源同 tab 有效,H5 页面和 App 的 WebView 不满足条件
任何试图绕过服务端、靠前端“悄悄通信”的方案,在 iOS WKWebView、Android 禁用 JSBridge、多进程 WebView 下都会失效
真正需要关注的,是服务端如何快速响应、避免轮询延迟,以及 App 扫码失败时是否提供 fallback(如手动输入 loginId)。这些细节比“怎么联动”更影响实际交付质量。
uni.scanCodeloginIdhttps://api.example.com/auth/qrcode?loginId=abc123loginId/auth/status?loginId=abc123uni.chooseImageqrcode.jsuni.scanCodehmos-scanuni-qr-scannerloginId{ loginId: "abc123", userId: "wx_123456" }uni.navigateTologinIdSET login:abc123 "{status:'pending', createdAt:1745593200}" EX 180status: 'success'loginId{ status: 'success', token: 'xxx' }status: 'expired'localStoragebroadcastChannel