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

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


🔗 项目源码地址


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

  • 点个赞 👍
  • 收藏 ⭐
  • 评论交流 💬
  • 关注我 👇 获取后续实战内容
相关推荐
划破黑暗的第一缕曙光4 小时前
[C++]:5.STL:string(2)
java·c++·redis
hhhjhl4 小时前
Undici 跨端三方库仓颉适配全流程
java·开发语言·ubuntu
wangchunyu1144 小时前
JAVA JVM内存结构与运行时数据区
java·开发语言·jvm
光锥智能5 小时前
海康机器人举行2026移动机器人新品发布会:箱式存拣升级,「明智」系列发布
java·前端·机器人
行思理5 小时前
Nginx 跨站请求(CORS)配置完全指南:从原理到生产实践
java·前端·nginx
小溪学编程5 小时前
Spring @Bean 与 @Component 注解的区别详解
java·后端·spring
IT_陈寒5 小时前
Python的列表推导式用不好真的会爆内存你知道吗
前端·人工智能·后端
Wang's Blog5 小时前
Java 项目实战: 交友项目 - 圈子互动章总结与自检清单
java·bootstrap·交友
xyouyuweizhu6 小时前
字节流与字符流:Java IO 的两条主线该怎么选
java·开发语言·python
代码方舟6 小时前
零信任架构实战:基于天远人企关联构建自动化供应链核心企业关联穿透与利益冲突审查网关
java·人工智能·架构·自动化