本文是「EduCore 教务系统实战系列」第 5 篇,将介绍我如何实现一个不依赖微信或 App的扫码登录机制,仅通过 PC 页面 + 手机浏览器,完成账户快速登录,适用于中后台系统、管理平台等场景。
🎯 背景:为什么要做网页扫码登录?
在一些办公、后台管理系统中,用户更习惯在 PC 上操作。但:
- 用户记不住密码;
- 多个账号切换不方便;
- 登录流程繁琐。
扫码登录可以让用户在手机浏览器中快速确认身份,自动完成 PC 登录,提升体验。
而且:无需微信开发者账号、无需授权接口,方案完全自主可控,部署即用。
🔍 实现思路概览
整体设计目标:
- ✅ PC 显示二维码;
- ✅ 手机扫描后跳转确认页;
- ✅ 用户点击"确认登录";
- ✅ 后端记录状态并推送给 PC;
- ✅ PC 检测到确认后自动登录;
🔁 完整流程图(强烈建议附图)
plaintext
[1] PC 浏览器请求二维码
↓
[2] 后端生成 UUID,存入 Redis(状态=未确认)
↓
[3] PC 页面展示 UUID 对应二维码
↓
[4] 手机扫描 → 跳转到 /qr-confirm?uuid=xxx
↓
[5] 手机端用户点击"确认登录"
↓
[6] 后端更新 Redis 中 uuid 状态=已确认 + 绑定用户信息
↓
[7] PC 页面定时轮询 /check-login?uuid=xxx
↓
[8] 检测到确认 → 返回 JWT Token
↓
[9] PC 自动完成登录,跳转主页面
🧱 技术选型与依赖说明
| 模块 | 技术栈 |
|---|---|
| 前端扫码页面 | Vue3 + Element Plus + QRCode.vue |
| 后端状态存储 | Redis(用于临时缓存登录状态) |
| 前端轮询 | JS 定时器 setInterval + Axios 请求 |
| Token 认证 | Spring Boot + JWT(与普通登录一致) |
💡 核心设计点说明
1. UUID 是核心标识
每次扫码登录流程中,系统会生成一个全局唯一 ID(UUID)用于标识一次登录会话:
java
String uuid = UUID.randomUUID().toString();
redisTemplate.opsForValue().set("login:uuid:" + uuid, "UNCONFIRMED", 3, TimeUnit.MINUTES);
用于防止伪造、多次使用、过期攻击。
2. 手机确认登录逻辑(/qr-confirm)
手机扫码跳转至:
bash
http://pc-ip:port/qr-confirm?uuid=xxxx
展示简单确认页面:
"是否确认使用 xxx 账户登录当前 PC 设备?" [确认登录] [取消]
点击"确认登录"后,向后端发送请求:
ts
axios.post("/api/qr/confirm", {
uuid: uuid,
username: xxx,
password: xxx
})
后端验证用户身份后,将 uuid 状态改为 "CONFIRMED:token",并写入 token:
java
redisTemplate.opsForValue().set("login:uuid:" + uuid, "CONFIRMED:" + jwtToken);
3. PC 定时轮询检查状态(/qr/check-login)
ts
setInterval(() => {
axios.get(`/api/qr/check-login?uuid=${uuid}`).then(res => {
if (res.data.token) {
localStorage.setItem("token", res.data.token);
router.push("/manager/home");
}
});
}, 1000);
后端代码:
java
@GetMapping("/check-login")
public R checkLogin(@RequestParam String uuid) {
String status = redisTemplate.opsForValue().get("login:uuid:" + uuid);
if (status != null && status.startsWith("CONFIRMED:")) {
String token = status.split("CONFIRMED:")[1];
return R.ok().put("token", token);
}
return R.error("未确认");
}
4. 权限与安全保障
- 每个 UUID 有效期仅 3 分钟,自动过期;
- 手机确认登录仍需账号密码校验;
- 登录后返回 JWT,与普通登录一致;
- 不保留任何中间身份信息,保证无状态;
- 无需微信开放平台,无需扫码 SDK;
🔒 扫码登录 vs 微信登录 对比
| 项目 | 网页扫码登录 | 微信扫码登录 |
|---|---|---|
| 接入成本 | 极低 | 高(需申请微信开放平台) |
| 可控性 | 完全自主 | 依赖微信生态 |
| 平台限制 | 无,任意设备浏览器 | 仅限微信支持 |
| 接入难度 | ⭐ | ⭐⭐⭐⭐ |
| 推荐程度 | ⭐⭐⭐⭐⭐ | ⭐⭐ |
📦 项目结构片段
plaintext
├── controller
│ └── QrLoginController.java
├── vue-pages
│ ├── QrLogin.vue // PC 显示二维码
│ └── QrConfirm.vue // 手机确认页面
├── utils
│ └── QrUtils.js // 生成二维码组件
✅ 效果展示(建议配图)
- PC 显示二维码
- 手机扫码跳转确认页
- 点击"确认登录"后,PC 页面自动跳转至主页面
🔚 总结
通过这一方案,我成功实现了:
- ✅ 无第三方依赖的网页扫码登录功能;
- ✅ 与普通账号密码登录共用认证体系(JWT);
- ✅ 使用 Redis 实现无状态的登录状态协商;
- ✅ PC 与移动端通信通过 UUID + 轮询完成;
- ✅ 提升用户体验与系统专业度;
📌 下一篇预告
📌《使用 Vue3 + Axios 与 Spring Boot 高效对接(含 token 处理)》
你将看到前后端如何协同处理请求拦截、Token 传递、统一响应与异常处理等问题。
🔗 项目源码地址
- GitHub:gitee.com/codevibe/gr...
- 扫码登录代码已上传,可一键启动体验
🙋♂️ 如果你觉得这篇文章有帮助:
- 点个赞 👍
- 收藏 ⭐
- 评论交流 💬
- 关注我 👇 获取后续实战内容