手把手教会你实现扫码登录(附 Spring Boot + Vue 全套代码)
视频看了几百小时还迷糊关注我几分钟让你秒懂你是否好奇微信、淘宝、GitHub 的“扫码登录”是怎么实现的为什么手机确认后网页就自动登录了二维码里到底存了什么后端如何知道用户“已扫码”今天我们就用Spring Boot Vue从零实现一个高仿微信扫码登录系统包含✅ 生成带唯一 ID 的二维码✅ 手机端模拟扫码确认✅ 网页端轮询/长轮询检测状态✅ 登录成功跳转小白也能跟着做 一、扫码登录的核心原理扫码登录本质是“设备间通信”流程如下关键点二维码内容 一个临时唯一 IDscene_id手机扫码 向服务器报告 “这个 ID 被谁确认了”网页轮询 不断问 “这个 ID 有结果了吗” 二、技术选型模块技术后端Spring Boot 3.x Redis前端网页Vue 3 Axios qrcode.vue手机端模拟Postman / 另一个 API 调用二维码生成com.google.zxing会话存储Redis存 scene_id → user 关系 三、后端实现Spring Boot1. 添加依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency dependency groupIdcom.google.zxing/groupId artifactIdjavase/artifactId version3.5.1/version /dependency2. 配置 Redisapplication.ymlspring: redis: host: localhost port: 63793. 核心接口定义RestController RequestMapping(/scan) public class ScanLoginController { Autowired private RedisTemplateString, String redisTemplate; private static final String SCENE_PREFIX scan_login:; private static final long EXPIRE_SECONDS 300; // 5分钟过期 /** * 1. 网页端获取登录二维码 */ GetMapping(/qrcode) public ResponseEntitybyte[] getQrCode() throws Exception { // 生成唯一 scene_id String sceneId UUID.randomUUID().toString().replace(-, ); String key SCENE_PREFIX sceneId; // 存入 Redis初始状态为 created redisTemplate.opsForValue().set(key, created, EXPIRE_SECONDS, TimeUnit.SECONDS); // 二维码内容指向扫码确认接口的 URL含 scene_id String content http://localhost:8080/scan/confirm?sceneId sceneId; // 生成二维码图片PNG 字节数组 byte[] qrCodeImage QrCodeUtil.createQrCode(content, 300, 300); return ResponseEntity.ok() .header(sceneId, sceneId) // 返回 sceneId 给前端 .contentType(MediaType.IMAGE_PNG) .body(qrCodeImage); } /** * 2. 手机端扫码后确认登录模拟 */ PostMapping(/confirm) public String confirmLogin(RequestParam String sceneId, RequestParam String userId) { String key SCENE_PREFIX sceneId; Boolean exists redisTemplate.hasKey(key); if (Boolean.TRUE.equals(exists)) { // 将状态更新为用户ID表示已确认 redisTemplate.opsForValue().set(key, userId, EXPIRE_SECONDS, TimeUnit.SECONDS); return 确认成功; } return sceneId 无效或已过期; } /** * 3. 网页端轮询查询登录状态 */ GetMapping(/status) public ResponseEntityMapString, Object checkStatus(RequestParam String sceneId) { String key SCENE_PREFIX sceneId; String value redisTemplate.opsForValue().get(key); MapString, Object result new HashMap(); if (value null) { result.put(status, expired); // 已过期 } else if (created.equals(value)) { result.put(status, waiting); // 等待扫码 } else { result.put(status, success); result.put(userId, value); // 登录用户ID // 可在此生成 JWT 或 Session } return ResponseEntity.ok(result); } }4. 二维码工具类public class QrCodeUtil { public static byte[] createQrCode(String content, int width, int height) throws Exception { BitMatrix bitMatrix new MultiFormatWriter() .encode(content, BarcodeFormat.QR_CODE, width, height); ByteArrayOutputStream pngOutputStream new ByteArrayOutputStream(); MatrixToImageWriter.writeToStream(bitMatrix, PNG, pngOutputStream); return pngOutputStream.toByteArray(); } } 四、前端实现Vue 31. 安装依赖npm install axios qrcode.vue2. 扫码登录页面ScanLogin.vuetemplate div v-if!isLoggedIn h2扫码登录/h2 div v-ifqrCodeUrl !-- 显示二维码 -- img :srcqrCodeUrl alt扫码登录 / p{{ statusText }}/p /div div v-else加载中.../div /div div v-else h2登录成功欢迎 {{ userId }}/h2 button clicklogout退出/button /div /template script setup import { ref, onMounted } from vue import axios from axios const qrCodeUrl ref() const sceneId ref() const statusText ref(请使用手机扫码) const isLoggedIn ref(false) const userId ref() // 获取二维码 const fetchQrCode async () { const res await axios.get(/scan/qrcode, { responseType: blob }) sceneId.value res.headers[sceneid] // 从响应头获取 sceneId qrCodeUrl.value URL.createObjectURL(res.data) pollStatus() // 开始轮询 } // 轮询检查状态 const pollStatus () { const timer setInterval(async () { try { const res await axios.get(/scan/status?sceneId${sceneId.value}) const { status, userId: uid } res.data if (status success) { clearInterval(timer) userId.value uid isLoggedIn.value true statusText.value 登录成功 } else if (status expired) { clearInterval(timer) statusText.value 二维码已过期请刷新重试 } else { statusText.value 等待扫码... } } catch (e) { console.error(e) } }, 2000) // 每2秒查一次 } const logout () { isLoggedIn.value false qrCodeUrl.value fetchQrCode() } onMounted(() { fetchQrCode() }) /script 五、模拟手机扫码测试用打开网页看到二维码用 Postman 或 curl 模拟手机扫码确认curl -X POST http://localhost:8080/scan/confirm?sceneId你的sceneIduserId10001网页端2 秒内自动跳转到“登录成功”页面⚠️ 六、反例 注意事项❌ 反例1用数据库代替 Redis数据库写入慢高并发下性能差必须用 Redis 这类内存数据库支持高频率读写。❌ 反例2scene_id 不设过期用户关闭页面后scene_id 永久占用内存务必设置 TTL如 5 分钟。❌ 反例3二维码内容直接放用户信息// 错误 String content userId10001;后果任何人扫了都能登录✅ 正确做法二维码只放临时 scene_id身份由手机端安全上报。✅ 安全加固建议scene_id 用 UUID不可预测确认接口加鉴权如手机端需先登录同一 scene_id 只能使用一次确认后立即删除或标记生产环境用 HTTPS防止中间人攻击。 七、进阶优化方向优化点方案减少轮询压力改用 WebSocket 或 SSE服务端推送支持多端登录scene_id 绑定设备类型防刷机制限制 IP 每分钟生成二维码次数日志追踪记录 scene_id 生命周期 总结扫码登录 临时 ID 状态同步二维码内容 ≠ 用户信息而是回调地址 scene_id核心数据结构Redis 中scene_id → user_id网页通过轮询感知状态变化安全关键scene_id 随机、短期有效、确认接口受保护。掌握这套逻辑你不仅能实现扫码登录还能扩展到扫码支付、扫码授权等场景视频看了几百小时还迷糊关注我几分钟让你秒懂

相关新闻

Sa-Token 如何忽略鉴权?三种方式让你灵活放行接口!

Sa-Token 如何忽略鉴权?三种方式让你灵活放行接口!

视频看了几百小时还迷糊?关注我,几分钟让你秒懂! 在使用 Sa-Token 做权限控制时,我们通常希望: /login、/register、/health 等接口 无需登录即可访问;Swagger 文档、静态资源、验证码接口 跳过鉴权&#…

2026/7/6 14:57:18 阅读更多 →
【Android毕设全套源码+文档】ssm基于Android的学籍异动管理平台的设计与实现(丰富项目+远程调试+讲解+定制)

【Android毕设全套源码+文档】ssm基于Android的学籍异动管理平台的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/6 22:30:39 阅读更多 →
【Android毕设源码分享】基于springboot+Android的的设计与实现(程序+文档+代码讲解+一条龙定制)

【Android毕设源码分享】基于springboot+Android的的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/6 12:21:54 阅读更多 →

最新新闻

雀魂牌谱屋:如何用3个数据分析模块快速提升你的麻将水平?

雀魂牌谱屋:如何用3个数据分析模块快速提升你的麻将水平?

雀魂牌谱屋:如何用3个数据分析模块快速提升你的麻将水平? 【免费下载链接】amae-koromo 雀魂牌谱屋 (See also: https://github.com/SAPikachu/amae-koromo-scripts ) 项目地址: https://gitcode.com/gh_mirrors/am/amae-koromo 你是否经常在雀魂…

2026/7/7 14:06:43 阅读更多 →
终极指南:用tchMaterial-parser一键下载国家中小学智慧教育平台电子课本

终极指南:用tchMaterial-parser一键下载国家中小学智慧教育平台电子课本

终极指南:用tchMaterial-parser一键下载国家中小学智慧教育平台电子课本 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具,帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载,让您更方便地获取课本…

2026/7/7 14:06:43 阅读更多 →
STM32F205RB与DS28EC20 EEPROM配置存储方案详解

STM32F205RB与DS28EC20 EEPROM配置存储方案详解

1. 为什么选择DS28EC20保存用户配置? 在嵌入式系统中保存用户设置和偏好,常见的方案有Flash存储、FRAM、EEPROM等。DS28EC20作为1-Wire接口的EEPROM芯片,在STM32F205RB项目中具有独特优势: 物理特性 :20480位&#x…

2026/7/7 14:06:43 阅读更多 →
STM32与DS28EC20 EEPROM嵌入式数据存储方案详解

STM32与DS28EC20 EEPROM嵌入式数据存储方案详解

1. 项目背景与核心需求 在嵌入式系统开发中,用户设置和偏好的持久化存储是一个常见但关键的需求。传统方案如Flash存储存在擦写次数有限(通常约10万次)、操作复杂等问题,而基于DS28EC20 EEPROM芯片的方案则能完美解决这些痛点。 …

2026/7/7 14:06:43 阅读更多 →
终极小说下载器指南:轻松收藏全网小说,打造个人数字图书馆

终极小说下载器指南:轻松收藏全网小说,打造个人数字图书馆

终极小说下载器指南:轻松收藏全网小说,打造个人数字图书馆 【免费下载链接】novel-downloader 一个可扩展的通用型小说下载器。 项目地址: https://gitcode.com/gh_mirrors/no/novel-downloader 在数字内容快速变化的今天,你是否曾因心…

2026/7/7 14:04:42 阅读更多 →
免费解锁Wand专业版:三步实现无限游戏修改体验

免费解锁Wand专业版:三步实现无限游戏修改体验

免费解锁Wand专业版:三步实现无限游戏修改体验 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 想要摆脱Wand免费版的2小时限制,享…

2026/7/7 14:04:42 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻