无微信依赖!纯网页扫码登录实现方案详解

本文是「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 传递、统一响应与异常处理等问题。


🔗 项目源码地址


🙋‍♂️ 如果你觉得这篇文章有帮助:

  • 点个赞 👍
  • 收藏 ⭐
  • 评论交流 💬
  • 关注我 👇 获取后续实战内容
相关推荐
书源丶22 分钟前
三十六、File 类与 IO 流基础——文件操作的「第一步」
java
刀法如飞28 分钟前
Go数组去重的20种实现方式,AI时代解决问题的不同思路
后端·算法·go
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题】【Java基础篇】第30题:JDK动态代理和CGLIB动态代理有什么区别
java·开发语言·后端·面试·代理模式
swipe1 小时前
别再把 AI 聊天做成纯文本:从 agui 这个前后端项目,拆解“可感知工具调用”的流式 AI UI
后端·langchain·llm
GetcharZp1 小时前
GitHub 爆火!纯 Go 编写的文件同步神器 Syncthing,凭什么成为程序员的标配?
后端
hERS EOUS1 小时前
SpringBoot 使用 spring.profiles.active 来区分不同环境配置
spring boot·后端·spring
DFT计算杂谈1 小时前
wannier90 参数详解大全
java·前端·css·html·css3
LucianaiB1 小时前
我用飞书多维表做了一个 AI 活动推荐智能体:每天自动催我别错过截止日期!
后端
marsh02061 小时前
43 openclaw熔断与降级:保障系统在异常情况下的可用性
java·运维·网络·ai·编程·技术
张健11564096482 小时前
临界区和同一线程上锁
java·开发语言·jvm