news 2026/4/18 10:51:42

PC 端微信扫码登录实现教程(Java + Vue 2)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PC 端微信扫码登录实现教程(Java + Vue 2)
在 PC 端实现微信扫码登录时,用户用手机微信扫码后,PC 端要能自动登录。本文整理了完整流程,包括前端、后端实现和流程图。

一、核心流程概览

PC 扫码登录本质是通过唯一 sessionId(state)绑定一次扫码会话。流程如下:

PC端 /wechat/login 页面 ↓ 显示二维码 + sessionId 手机微信扫码二维码 ↓ 微信官方授权页面(无需前端实现) ↓ 用户确认授权 微信回调后端 /wechat/callback ↓ 后端用 code 换取 access_token + openid ↓ 后端生成系统 token,并更新 sessionId 状态为 success PC端轮询 /api/wechat/qr/status?sessionId=xxx ↓ 获取 token ↓ 保存 token → 登录成功 → 跳转首页

🔑 要点:

  • sessionId:每次生成二维码唯一标识扫码会话
  • 手机授权页面:微信官方提供,前端无需处理
  • PC 端通过轮询或 WebSocket 查询授权状态

二、前端实现(Vue 2)

1️⃣ 二维码显示页面

WechatLogin.vue

<template> <div class="wechat-login"> <h2>微信扫码登录</h2> <div v-if="qrUrl"> <p>请使用微信扫码登录</p> <img :src="qrUrl" alt="微信扫码登录二维码" /> </div> <div v-else> <p>二维码生成中...</p> </div> </div> </template> <script> import axios from 'axios'; export default { data() { return { qrUrl: '', }; }, mounted() { this.fetchQrCode(); }, methods: { async fetchQrCode() { try { const res = await axios.get('/api/wechat/qr'); this.qrUrl = res.data.qrUrl; // 获取二维码 URL 中的 sessionId const sessionId = new URL(this.qrUrl).searchParams.get('state'); this.startPolling(sessionId); } catch (err) { console.error('生成二维码失败', err); } }, startPolling(sessionId) { const interval = setInterval(async () => { const res = await axios.get(`/api/wechat/qr/status?sessionId=${sessionId}`); if (res.data.status === 'success') { clearInterval(interval); localStorage.setItem('token', res.data.token); window.location.href = '/'; } else if (res.data.status === 'failed' || res.data.status === 'expired') { clearInterval(interval); alert('扫码登录失败或二维码过期,请重新扫码'); } }, 2000); } } }; </script> <style scoped> .wechat-login { text-align: center; padding: 50px; } .wechat-login img { width: 250px; height: 250px; } </style>

前端说明:

  • /api/wechat/qr返回二维码 URL
  • 轮询/api/wechat/qr/status?sessionId=xxx获取授权结果

三、后端实现(Java + Spring Boot)

1️⃣ 数据结构

import java.time.LocalDateTime; public class WechatLoginSession { private String sessionId; private String status; // pending / success / failed private String token; private LocalDateTime expireTime; // getter / setter }
  • 内存 Map保存会话(生产环境可用 Redis)
import java.util.concurrent.ConcurrentHashMap; public class WechatSessionStore { public static final ConcurrentHashMap<String, WechatLoginSession> sessionMap = new ConcurrentHashMap<>(); }

2️⃣ 生成二维码 URL

@GetMapping("/api/wechat/qr") public Map<String, String> getQrCode() throws Exception { String sessionId = UUID.randomUUID().toString(); WechatLoginSession session = new WechatLoginSession(); session.setSessionId(sessionId); session.setStatus("pending"); session.setExpireTime(LocalDateTime.now().plusMinutes(5)); WechatSessionStore.sessionMap.put(sessionId, session); String redirectUriEncoded = URLEncoder.encode("https://yourdomain.com/api/wechat/callback", "UTF-8"); String qrUrl = "https://open.weixin.qq.com/connect/qrconnect?" + "appid=" + APPID + "&redirect_uri=" + redirectUriEncoded + "&response_type=code" + "&scope=snsapi_login" + "&state=" + sessionId + "#wechat_redirect"; return Collections.singletonMap("qrUrl", qrUrl); }

3️⃣ 微信回调处理

@GetMapping("/api/wechat/callback") public String callback(@RequestParam String code, @RequestParam String state) { WechatLoginSession session = WechatSessionStore.sessionMap.get(state); if (session == null) { return "登录会话不存在或已过期"; } try { // 用 code 换取 access_token + openid RestTemplate restTemplate = new RestTemplate(); String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + "appid=" + APPID + "&secret=" + APPSECRET + "&code=" + code + "&grant_type=authorization_code"; Map<String, Object> tokenResp = restTemplate.getForObject(url, Map.class); String openid = (String) tokenResp.get("openid"); // 生成系统 token String systemToken = "token-" + openid + "-" + System.currentTimeMillis(); session.setStatus("success"); session.setToken(systemToken); return "授权成功,请返回 PC 页面"; } catch (Exception e) { e.printStackTrace(); session.setStatus("failed"); return "授权失败"; } }

4️⃣ PC 端轮询接口

@GetMapping("/api/wechat/qr/status") public Map<String, Object> checkQrStatus(@RequestParam String sessionId) { WechatLoginSession session = WechatSessionStore.sessionMap.get(sessionId); if (session == null) { return Map.of("status", "expired"); } if ("success".equals(session.getStatus())) { String token = session.getToken(); WechatSessionStore.sessionMap.remove(sessionId); // 可选移除 return Map.of("status", "success", "token", token); } if ("failed".equals(session.getStatus())) { return Map.of("status", "failed"); } return Map.of("status", "pending"); }

四、流程图

flowchart TD A[PC端请求 /wechat/login] --> B[后端生成二维码 + sessionId] B --> C[前端显示二维码] D[用户用手机扫码] --> E[微信授权页面(微信自带)] E --> F[用户确认授权] F --> G[微信回调后端 /wechat/callback] G --> H[后端换取 access_token + openid] H --> I[后端生成系统 token,更新 sessionId 状态] C --> J[PC端轮询 /api/wechat/qr/status?sessionId=xxx] J -->|status=success| K[PC端保存 token,登录成功]

五、总结

  • 二维码 & sessionId:每次生成唯一二维码,绑定登录会话
  • 授权页面:微信官方提供,前端无需处理
  • PC 端轮询或 WebSocket:获取授权结果
  • 后端处理:用 code 换 token,生成系统 token,更新 session 状态

这种方式可以安全、方便地实现PC 端扫码登录,用户体验与微信官方一致。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 22:50:05

VideoMAEv2:如何用自监督学习让AI真正看懂视频内容?

VideoMAEv2&#xff1a;如何用自监督学习让AI真正看懂视频内容&#xff1f; 【免费下载链接】VideoMAEv2 项目地址: https://gitcode.com/gh_mirrors/vi/VideoMAEv2 你是否曾经好奇&#xff0c;AI是如何像人类一样理解视频中复杂的动作和场景&#xff1f;传统的视频理解…

作者头像 李华
网站建设 2026/4/15 19:09:26

Dify文档频繁保存失败?(90%用户忽略的底层机制曝光)

第一章&#xff1a;Dify文档频繁保存失败&#xff1f;&#xff08;90%用户忽略的底层机制曝光&#xff09; 许多用户在使用 Dify 编辑长篇文档时&#xff0c;常遇到“保存失败”或“自动保存中断”的问题。表面上看是网络波动或操作失误&#xff0c;实则与 Dify 的客户端-服务端…

作者头像 李华
网站建设 2026/4/16 18:30:46

终极指南:5分钟掌握mimalloc,微软出品的高性能内存分配器

终极指南&#xff1a;5分钟掌握mimalloc&#xff0c;微软出品的高性能内存分配器 【免费下载链接】mimalloc mimalloc is a compact general purpose allocator with excellent performance. 项目地址: https://gitcode.com/GitHub_Trending/mi/mimalloc 想要让你的C/C程…

作者头像 李华
网站建设 2026/3/23 21:54:24

如何快速实现百度网盘免登录下载:普通用户的完整解决方案

如何快速实现百度网盘免登录下载&#xff1a;普通用户的完整解决方案 【免费下载链接】baiduwp-php A tool to get the download link of the Baidu netdisk / 一个获取百度网盘分享链接下载地址的工具 项目地址: https://gitcode.com/gh_mirrors/ba/baiduwp-php 还在为…

作者头像 李华
网站建设 2026/4/16 15:26:39

GLM-4.6V-Flash-WEB如何理解抽象画作的内容?

GLM-4.6V-Flash-WEB 如何理解抽象画作的内容&#xff1f; 在数字艺术展览越来越依赖交互体验的今天&#xff0c;一个核心问题浮现出来&#xff1a;当用户面对一幅没有具象人物、也无明确叙事线索的抽象画时&#xff0c;AI能否真正“读懂”它&#xff1f;不是简单识别出“红色方…

作者头像 李华
网站建设 2026/4/17 0:20:37

Dify附件ID存在性判断全攻略(实战代码+性能优化技巧)

第一章&#xff1a;Dify附件ID存在性判断的核心机制在 Dify 框架中&#xff0c;附件 ID 的存在性判断是确保数据完整性与资源访问安全的关键环节。系统通过唯一标识符&#xff08;Attachment ID&#xff09;对上传的文件进行索引和管理&#xff0c;在处理请求时需首先验证该 ID…

作者头像 李华