news 2026/4/15 12:48:07

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/15 12:09:39

MBPFan:MacBook智能散热管理完整解决方案

MBPFan&#xff1a;MacBook智能散热管理完整解决方案 【免费下载链接】mbpfan 项目地址: https://gitcode.com/gh_mirrors/mb/mbpfan 你是否曾经在专注工作时被MacBook突然增大的风扇噪音打断&#xff1f;或者在运行大型软件时感觉设备烫手到担心硬件受损&#xff1f;这…

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

sd-webui-roop 面部替换终极指南:从入门到精通

sd-webui-roop 面部替换终极指南&#xff1a;从入门到精通 【免费下载链接】sd-webui-roop roop extension for StableDiffusion web-ui 项目地址: https://gitcode.com/gh_mirrors/sd/sd-webui-roop 在本指南中&#xff0c;你将掌握如何使用sd-webui-roop这一强大的面部…

作者头像 李华
网站建设 2026/4/15 12:07:50

【Dify私有化部署终极指南】:从零开始掌握企业级部署全流程

第一章&#xff1a;Dify私有化部署概述Dify 是一个开源的低代码 AI 应用开发平台&#xff0c;支持快速构建基于大语言模型的智能应用。私有化部署允许企业将 Dify 完整运行在自有服务器或私有云环境中&#xff0c;保障数据安全与系统可控性&#xff0c;适用于对合规性、隐私保护…

作者头像 李华
网站建设 2026/4/12 20:48:09

聚势华商·智创未来 | 华商北京校友会年会庆典圆满落幕

2026年1月3日&#xff0c;星河华商书院华商北京校友会年会庆典在北京西国贸大酒店1号宴会厅隆重举行。本次活动以“聚势华商智创未来”为核心口号&#xff0c;汇聚“聚势凝心凝共识&#xff0c;智创赋能启新程&#xff0c;华商同心传薪火&#xff0c;逐梦同行向未来”的奋进力量…

作者头像 李华