2026/2/8 18:05:39
网站建设
项目流程
广州木马网站建设公司怎么样,网络安全行业公司排名,文化公司网页设计,宝安做网站哪家好在 PC 端实现微信扫码登录时#xff0c;用户用手机微信扫码后#xff0c;PC 端要能自动登录。本文整理了完整流程#xff0c;包括前端、后端实现和流程图。一、核心流程概览PC 扫码登录本质是通过 唯一 sessionId#xff08;state#xff09; 绑定一次扫码会话。流程如下用户用手机微信扫码后PC 端要能自动登录。本文整理了完整流程包括前端、后端实现和流程图。一、核心流程概览PC 扫码登录本质是通过唯一 sessionIdstate绑定一次扫码会话。流程如下PC端 /wechat/login 页面 ↓ 显示二维码 sessionId 手机微信扫码二维码 ↓ 微信官方授权页面无需前端实现 ↓ 用户确认授权 微信回调后端 /wechat/callback ↓ 后端用 code 换取 access_token openid ↓ 后端生成系统 token并更新 sessionId 状态为 success PC端轮询 /api/wechat/qr/status?sessionIdxxx ↓ 获取 token ↓ 保存 token → 登录成功 → 跳转首页 要点sessionId每次生成二维码唯一标识扫码会话手机授权页面微信官方提供前端无需处理PC 端通过轮询或 WebSocket 查询授权状态二、前端实现Vue 21️⃣ 二维码显示页面WechatLogin.vuetemplate div classwechat-login h2微信扫码登录/h2 div v-ifqrUrl p请使用微信扫码登录/p img :srcqrUrl 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?sessionIdxxx获取授权结果三、后端实现Java Spring Boot1️⃣ 数据结构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保存会话生产环境可用 Redisimport java.util.concurrent.ConcurrentHashMap; public class WechatSessionStore { public static final ConcurrentHashMapString, WechatLoginSession sessionMap new ConcurrentHashMap(); }2️⃣ 生成二维码 URLGetMapping(/api/wechat/qr) public MapString, 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_typecode scopesnsapi_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_typeauthorization_code; MapString, 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 MapString, 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?sessionIdxxx] J --|statussuccess| K[PC端保存 token登录成功]五、总结二维码 sessionId每次生成唯一二维码绑定登录会话授权页面微信官方提供前端无需处理PC 端轮询或 WebSocket获取授权结果后端处理用 code 换 token生成系统 token更新 session 状态这种方式可以安全、方便地实现PC 端扫码登录用户体验与微信官方一致。