springboot結合vue2實現(xiàn)微信掃碼登錄的完整指南
要實現(xiàn) Spring Boot + Vue2 的微信掃碼登錄功能,需遵循微信開放平臺的 OAuth2.0 授權流程。以下是詳細步驟:
一、準備工作
1.注冊微信開放平臺賬號?:訪問 微信開放平臺,注冊并認證企業(yè)賬號(個人賬號不支持網站應用)。
2.創(chuàng)建網站應用?
- 進入「管理中心」→「創(chuàng)建網站應用」,填寫應用名稱、域名等信息。
- 審核通過后,獲取 AppID? 和 AppSecret(后續(xù)接口調用需使用)。
3.配置授權回調域?:在應用詳情頁設置「授權回調域」(如 example.com,無需加 http://或路徑),確保前端頁面與回調域名一致。
二、后端(Spring Boot)實現(xiàn)
1. 添加依賴
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- HTTP 客戶端(用于調用微信 API) -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- JSON 解析 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
2. 配置文件(application.yml)
wechat:
login:
appid: your_appid # 微信開放平臺 AppID
secret: your_secret # 微信開放平臺 AppSecret
redirect-uri: http://localhost:8080/api/wechat/callback # 回調接口地址(需與開放平臺配置一致)
scope: snsapi_login # 授權作用域(固定為 snsapi_login)
3. 核心代碼實現(xiàn)
(1) 配置類讀取參數(shù)
@Component
@ConfigurationProperties(prefix = "wechat.login")
public class WeChatConfig {
private String appid;
private String secret;
private String redirectUri;
private String scope;
// getter/setter
}
(2) 生成微信登錄二維碼 URL
微信掃碼登錄需引導用戶跳轉至微信授權頁,生成帶參數(shù)的 URL:
@Service
public class WeChatAuthService {
@Autowired
private WeChatConfig weChatConfig;
/**
* 生成微信掃碼登錄的授權 URL
*/
public String generateLoginUrl() {
String baseUrl = "https://open.weixin.qq.com/connect/qrconnect";
Map<String, String> params = new HashMap<>();
params.put("appid", weChatConfig.getAppid());
params.put("redirect_uri", URLEncoder.encode(weChatConfig.getRedirectUri(), StandardCharsets.UTF_8));
params.put("response_type", "code");
params.put("scope", weChatConfig.getScope());
params.put("state", "STATE"); // 可選:隨機字符串,防止 CSRF 攻擊
// 拼接 URL
String url = baseUrl + "?";
for (Map.Entry<String, String> entry : params.entrySet()) {
url += entry.getKey() + "=" + entry.getValue() + "&";
}
return url.substring(0, url.length() - 1) + "#wechat_redirect"; // 必須以 #wechat_redirect 結尾
}
}
(3) 回調接口處理授權碼(Code)
用戶掃碼確認登錄后,微信會重定向到 redirect_uri并攜帶 code和 state,后端需通過 code換取 access_token和用戶信息:
@RestController
@RequestMapping("/api/wechat")
public class WeChatCallbackController {
@Autowired
private WeChatAuthService weChatAuthService;
@Autowired
private RestTemplate restTemplate; // 注入 RestTemplate 用于 HTTP 請求
/**
* 微信授權回調接口
*/
@GetMapping("/callback")
public ResponseEntity<?> handleCallback(
@RequestParam String code,
@RequestParam String state) {
try {
// 1. 用 code 換取 access_token
String tokenUrl = String.format(
"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
weChatConfig.getAppid(), weChatConfig.getSecret(), code
);
String tokenResult = restTemplate.getForObject(tokenUrl, String.class);
JSONObject tokenJson = JSON.parseObject(tokenResult);
if (tokenJson.containsKey("errcode")) {
return ResponseEntity.badRequest().body("獲取 access_token 失?。? + tokenJson.getString("errmsg"));
}
String accessToken = tokenJson.getString("access_token");
String openId = tokenJson.getString("openid");
// 2. 用 access_token 和 openid 獲取用戶信息
String userInfoUrl = String.format(
"https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s",
accessToken, openId
);
String userInfoResult = restTemplate.getForObject(userInfoUrl, String.class);
JSONObject userInfoJson = JSON.parseObject(userInfoResult);
if (userInfoJson.containsKey("errcode")) {
return ResponseEntity.badRequest().body("獲取用戶信息失?。? + userInfoJson.getString("errmsg"));
}
// 3. 處理用戶信息(如創(chuàng)建/更新本地用戶,生成 JWT Token 等)
String nickname = userInfoJson.getString("nickname");
String headImgUrl = userInfoJson.getString("headimgurl");
// ... 其他字段(sex、province、city 等)
// 示例:返回用戶信息給前端(實際需根據(jù)業(yè)務生成 Token)
Map<String, Object> result = new HashMap<>();
result.put("openid", openId);
result.put("nickname", nickname);
result.put("headimgurl", headImgUrl);
return ResponseEntity.ok(result);
} catch (Exception e) {
return ResponseEntity.internalServerError().body("登錄失?。? + e.getMessage());
}
}
}
(4) 提供生成登錄 URL 的接口(供前端調用)
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private WeChatAuthService weChatAuthService;
@GetMapping("/wechat/login-url")
public ResponseEntity<String> getWeChatLoginUrl() {
String loginUrl = weChatAuthService.generateLoginUrl();
return ResponseEntity.ok(loginUrl);
}
}
三、前端(Vue2)實現(xiàn)
1. 安裝依賴(可選)
如需展示二維碼,可使用 qrcode庫將微信登錄 URL 轉換為二維碼圖片:
npm install qrcode --save
2. 核心代碼實現(xiàn)
(1) 獲取微信登錄 URL 并生成二維碼
<template>
<div class="wechat-login">
<h3>微信掃碼登錄</h3>
<!-- 二維碼展示區(qū)域 -->
<canvas id="wechat-qrcode"></canvas>
<p v-if="errorMsg" class="error">{{ errorMsg }}</p>
</div>
</template>
<script>
import QRCode from 'qrcode';
import axios from 'axios';
export default {
data() {
return {
wechatLoginUrl: '',
errorMsg: ''
};
},
mounted() {
this.getWeChatLoginUrl();
},
methods: {
// 從后端獲取微信登錄 URL
async getWeChatLoginUrl() {
try {
const res = await axios.get('http://localhost:8080/api/auth/wechat/login-url');
this.wechatLoginUrl = res.data;
this.generateQRCode(this.wechatLoginUrl);
} catch (err) {
this.errorMsg = '獲取登錄鏈接失敗,請重試';
console.error(err);
}
},
// 生成二維碼
generateQRCode(url) {
const canvas = document.getElementById('wechat-qrcode');
QRCode.toCanvas(canvas, url, { width: 200 }, (error) => {
if (error) {
this.errorMsg = '生成二維碼失敗';
console.error(error);
}
});
}
}
};
</script>
<style scoped>
.wechat-login { text-align: center; margin-top: 50px; }
.error { color: red; margin-top: 10px; }
#wechat-qrcode { margin: 20px auto; }
</style>
(2) 處理登錄成功后的回調
微信授權成功后,后端會重定向到 redirect_uri(即后端的 /api/wechat/callback),并將用戶信息返回給前端。若前端需要直接接收用戶信息(而非后端重定向),可調整流程:
- 后端回調接口驗證
code后,將用戶信息存儲到 Session 或 Redis,然后重定向到前端頁面(如http://localhost:8081/login-success?token=xxx)。 - 前端監(jiān)聽路由變化,在
login-success頁面獲取 Token 并完成本地登錄狀態(tài)保存。
四、關鍵注意事項
HTTPS 要求:生產環(huán)境必須使用 HTTPS,否則微信授權可能失敗(開發(fā)環(huán)境可暫時使用 HTTP,但需確?;卣{域名與開放平臺配置一致)。
跨域問題:若前后端分離部署,需在后端配置 CORS 允許前端域名訪問:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:8081") // 前端域名
.allowedMethods("GET", "POST")
.allowCredentials(true);
}
}
安全性:
state參數(shù)需隨機生成并校驗,防止 CSRF 攻擊。access_token和openid需妥善保管,避免泄露。
錯誤處理:需處理微信 API 返回的錯誤碼(如 40029表示 code無效,40163表示 code已被使用)。
五、完整流程總結
- 前端請求后端獲取微信登錄 URL。
- 后端生成帶參數(shù)的微信授權 URL 并返回給前端。
- 前端將 URL 轉換為二維碼展示給用戶。
- 用戶掃碼并在微信客戶端確認登錄。
- 微信重定向到后端回調接口,攜帶
code。 - 后端通過
code換取access_token和用戶信息。 - 后端處理用戶信息(如生成 Token),并返回結果給前端。
- 前端根據(jù)返回結果完成本地登錄狀態(tài)保存(如存儲 Token 到 localStorage)。
通過以上步驟,即可實現(xiàn)基于 Spring Boot + Vue2 的微信掃碼登錄功能。
到此這篇關于springboot結合vue2實現(xiàn)微信掃碼登錄的完整指南的文章就介紹到這了,更多相關springboot微信掃碼登錄內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于MyBatis的數(shù)據(jù)持久化框架的使用詳解
Mybatis是一個優(yōu)秀的開源、輕量級持久層框架,它對JDBC操作數(shù)據(jù)庫的過程進行封裝。本文將為大家講解一下基于MyBatis的數(shù)據(jù)持久化框架的使用,感興趣的可以了解一下2022-08-08
如何解決SpringBoot2.x版本對Velocity模板不支持的方案
這篇文章主要介紹了如何解決SpringBoot2.x版本對Velocity模板不支持的方案,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12
SpringBoot集成ElasticSearch(ES)實現(xiàn)全文搜索功能
Elasticsearch是一個開源的分布式搜索和分析引擎,它被設計用于處理大規(guī)模數(shù)據(jù)集,它提供了一個分布式多用戶能力的全文搜索引擎,本文將給大家介紹SpringBoot集成ElasticSearch(ES)實現(xiàn)全文搜索功能,需要的朋友可以參考下2024-02-02
Jenkins自動化部署SpringBoot項目的實現(xiàn)
本文主要介紹了Jenkins自動化部署SpringBoot項目的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2023-01-01
java ssm框架實現(xiàn)分頁功能的示例代碼(oracle)
這篇文章主要介紹了java ssm框架實現(xiàn)分頁功能的示例代碼(oracle),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
解決java執(zhí)行cmd命令調用ffmpeg報錯Concat error - No such filter ''[0,0]
這篇文章主要介紹了java執(zhí)行cmd命令,調用ffmpeg報錯Concat error - No such filter '[0,0]'解決方法,本文通過截圖實例代碼說明給大家介紹的非常詳細,對大家的工作或學習有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
Spring Core動態(tài)代理的實現(xiàn)代碼
通過JDK的Proxy方式或者CGLIB方式生成代理對象的時候,相關的攔截器已經配置到代理對象中去了,接下來通過本文給大家介紹Spring Core動態(tài)代理的相關知識,需要的朋友可以參考下2021-10-10

