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

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


🔗 项目源码地址


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

  • 点个赞 👍
  • 收藏 ⭐
  • 评论交流 💬
  • 关注我 👇 获取后续实战内容
相关推荐
C雨后彩虹几秒前
计算疫情扩散时间
java·数据结构·算法·华为·面试
2601_949809594 分钟前
flutter_for_openharmony家庭相册app实战+我的Tab实现
java·javascript·flutter
vx_BS8133034 分钟前
【直接可用源码免费送】计算机毕业设计精选项目03574基于Python的网上商城管理系统设计与实现:Java/PHP/Python/C#小程序、单片机、成品+文档源码支持定制
java·python·课程设计
2601_9498683634 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
达文汐1 小时前
【困难】力扣算法题解析LeetCode332:重新安排行程
java·数据结构·经验分享·算法·leetcode·力扣
培风图南以星河揽胜1 小时前
Java版LeetCode热题100之零钱兑换:动态规划经典问题深度解析
java·leetcode·动态规划
启山智软1 小时前
【中大企业选择源码部署商城系统】
java·spring·商城开发
我真的是大笨蛋1 小时前
深度解析InnoDB如何保障Buffer与磁盘数据一致性
java·数据库·sql·mysql·性能优化
怪兽源码2 小时前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
恒悦sunsite2 小时前
Redis之配置只读账号
java·redis·bootstrap