Java實(shí)現(xiàn)微信掃碼授權(quán)登錄完整步驟
一直想實(shí)現(xiàn)一下微信的掃碼登錄,現(xiàn)在終于來(lái)實(shí)踐了。
要想實(shí)現(xiàn)微信的掃碼登錄肯定是直接瀏覽微信的官方開(kāi)發(fā)者文檔,從中就可以獲取一切的用法。
實(shí)現(xiàn)步驟
創(chuàng)建服務(wù)號(hào)的測(cè)試號(hào)
- 首先要?jiǎng)?chuàng)建一個(gè)測(cè)試號(hào),用于微信接口的調(diào)試,創(chuàng)建測(cè)試號(hào)地址
創(chuàng)建好了之后是這樣的:
其中的 URL 是需要自己填寫(xiě)的,這個(gè)是接收微信事件的回調(diào)地址,微信會(huì)給你推送事件,這個(gè)配置接口我們后面寫(xiě),token 可以隨便寫(xiě),不過(guò)后端符合微信的驗(yàn)證就好了。
創(chuàng)建一個(gè)SpringBoot的項(xiàng)目
這里直接通過(guò) IDEA 創(chuàng)建一個(gè)后端項(xiàng)目,然后引入,WxJava 的 SDK,方便進(jìn)行微信的交互,當(dāng)然也可以自己寫(xiě)和微信的交互,但是太繁雜了,別人都寫(xiě)好了,為什么還寫(xiě)呢???
- 引入 WxJava 管理公眾號(hào)
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>4.7.6-20250704.154059</version>
</dependency>
- 填寫(xiě)測(cè)試號(hào)的一些密鑰
wx.mp.appId=wx805bf0797a5f2911 # 必填 wx.mp.secret=72256cbeffd04ba3d592e133fe8f1f7a #必填 wx.mp.token=xwhking
- 配置使用的Bean
package com.xwhking.wxlogin.config;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WxConfig {
@Value("${wx.mp.appId}")
private String appId;
@Value("${wx.mp.secret}")
private String secret;
@Value("${wx.mp.token}")
private String token;
@Bean
public WxMpService wxMpService() {
WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
config.setAppId(appId);
config.setSecret(secret);
config.setToken(token);
WxMpService service = new WxMpServiceImpl();
service.setWxMpConfigStorage(config);
return service;
}
@Bean
public WxMpMessageRouter messageRouter(WxMpService wxMpService) {
final WxMpMessageRouter router = new WxMpMessageRouter(wxMpService);
// 這里可以添加各種消息處理器
return router;
}
}
- 編寫(xiě)接口,用于校驗(yàn),在測(cè)試號(hào)頁(yè)面,啟動(dòng)了后端,就可以讓微信校驗(yàn)成功(前提要配置網(wǎng)絡(luò)地址,需要內(nèi)網(wǎng)穿透)
微信校驗(yàn)流程圖,如下。
校驗(yàn)規(guī)格如下

@RestController
@RequestMapping("/wx/callback")
public class WxController {
@Autowired
private WxMpService wxMpService;
@GetMapping
public String verify(String signature, String timestamp, String nonce, String echostr) throws WxErrorException {
boolean b = wxMpService.checkSignature(timestamp, nonce, signature); //是否滿足微信的校驗(yàn)條件
if(b) {
return echostr;
}
return null;
}
}
內(nèi)網(wǎng)穿透
這里我介紹 cpolar下載 ,簡(jiǎn)單直接能夠免費(fèi)使用 24h 的http和https的隨機(jī)域名,當(dāng)然能夠永久,不過(guò)需要購(gòu)買罷了。其他的內(nèi)網(wǎng)穿透推薦ngrok , ftp 等

進(jìn)入網(wǎng)頁(yè)后點(diǎn)擊相應(yīng)的機(jī)型進(jìn)行下載就好了。
windows下載好后,直接點(diǎn)開(kāi)web就好

首先要登錄,在官網(wǎng)注冊(cè)就好了,進(jìn)入后是下面的樣子

編輯一下自己網(wǎng)站端口就行了,然后到在線隧道查看地址


掃碼登錄流程介紹
背景知識(shí),如果用戶沒(méi)有點(diǎn)擊授權(quán)信息的話,從微信掃碼只能夠獲得用戶的 OpenId,其他信息都獲取不到,但是一般我們登錄流程的話是需要用戶的昵稱,頭像,通過(guò)用戶的授權(quán),我們就可以直接獲取到了,不用用戶再次設(shè)置,這里用戶的手機(jī)號(hào)也是不能獲取到的。
- 用戶掃碼(只能或者一個(gè)帶有參數(shù)的url,要轉(zhuǎn)化成二維碼,這里沒(méi)有用前端了直接用草料二維碼進(jìn)行轉(zhuǎn)換),如果用戶掃碼了以后沒(méi)有關(guān)注公眾號(hào),那么當(dāng)用戶點(diǎn)擊關(guān)注以后才會(huì)推送掃碼關(guān)注事件,如果用戶已經(jīng)關(guān)注了那么手機(jī)會(huì)直接定位到會(huì)話頁(yè)面
- 用測(cè)試生成url
@SpringBootTest class WxLoginApplicationTests { @Autowired private WxMpService wxService; @Test void contextLoads() throws WxErrorException { System.out.println(wxService.getQrcodeService().qrCodeCreateTmpTicket(“user_info”, 30000).getUrl()); } }
接受微信推送的事件
返回給用戶信息,消息的響應(yīng)

用戶點(diǎn)擊鏈接進(jìn)行授權(quán)
用戶打開(kāi)地址,讓后端獲得權(quán)限,這里如果是域名備案了,那么會(huì)直接訪問(wèn),否則要自己到瀏覽器打開(kāi)網(wǎng)址才行。
此時(shí)獲取到了用戶的信息,已經(jīng)成功進(jìn)行了關(guān)聯(lián)啦!–>即能夠獲得用戶的昵稱,openid,頭像地址,這些信息一般來(lái)說(shuō)也夠了。
獲取到的信息
WxOAuth2UserInfo(openid=owO-dvkozjjzycXgtaCCgFbzxxxx, nickname=DIOIT, sex=0, city=, province=, country=, headImgUrl=https://thirdwx.qlogo.cn/mmopen/vi_32/GcAobrQM3uzlReTKGs7KtuPUibUrYXzt3hluJCXHr7DCMibYoB2viabQ2PsVPq8BfbsDwIozz1vpdAx4oib4gnTCdQ/132, unionId=null, privileges=[])
代碼實(shí)現(xiàn)
package com.xwhking.wxlogin.controller;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/wx/callback")
public class WxController {
@Autowired
private WxMpService wxMpService;
@Autowired
private WxMpMessageRouter wxMpMessageRouter;
@GetMapping
public String verify(String signature, String timestamp, String nonce, String echostr) throws WxErrorException {
boolean b = wxMpService.checkSignature(timestamp, nonce, signature); //是否滿足微信的校驗(yàn)條件
if(b) {
return echostr;
}
return null;
}
@PostMapping(produces = "application/xml; charset=UTF-8")
public String post(
@RequestBody String requestBody,
@RequestParam("signature") String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce,
@RequestParam(name = "encrypt_type", required = false) String encType,
@RequestParam(name = "msg_signature", required = false) String msgSignature) throws WxErrorException {
if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
throw new IllegalArgumentException("非法請(qǐng)求");
}
// 處理消息
WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
System.out.println("inMessage"+inMessage);
// 如果是二維碼掃描事件
if (inMessage.getEvent().equals(WxConsts.EventType.SCAN) ||
inMessage.getEvent().equals(WxConsts.EventType.SUBSCRIBE)) {
String redirectUri = "https://519e7b4c.r9.cpolar.cn/wx/callback/auth-callback"; // 你的回調(diào)地址
String scope = "snsapi_userinfo"; // 需要獲取用戶信息
String state = "random_state_123"; // 防CSRF攻擊
// 構(gòu)造授權(quán)URL
String authUrl = wxMpService.getOAuth2Service().buildAuthorizationUrl(redirectUri, scope, state);
// 可以回復(fù)消息
String APPID = wxMpService.getWxMpConfigStorage().getAppId();
String SECRET = wxMpService.getWxMpConfigStorage().getSecret();
String accessToken = wxMpService.getAccessToken();
WxMpUser wxMpUser = wxMpService.getUserService().userInfo(inMessage.getFromUser());
System.out.println(wxMpUser);
WxMpXmlOutMessage outMessage = WxMpXmlOutMessage.TEXT()
.content("<a href=\'"+authUrl+"\'>登錄</a>")
.fromUser(inMessage.getToUser())
.toUser(inMessage.getFromUser())
.build();
return outMessage.toXml();
}
// 其他消息交給路由器處理
WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
if (outMessage != null) {
return outMessage.toXml();
}
return "";
}
@GetMapping("/auth-callback")
public String callback(
@RequestParam("code") String code,
@RequestParam(value = "state", required = false) String state) {
// 驗(yàn)證state防止CSRF攻擊
try {
// 1. 用code換取access_token
WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(code);
// 2. 獲取用戶信息
WxOAuth2UserInfo userInfo = wxMpService.getOAuth2Service().getUserInfo(accessToken, null);
System.out.println(userInfo);
return "success";
} catch (WxErrorException e) {
return "授權(quán)失敗: " + e.getMessage();
}
}
}
總結(jié)
到此這篇關(guān)于Java實(shí)現(xiàn)微信掃碼授權(quán)登錄的文章就介紹到這了,更多相關(guān)Java微信掃碼授權(quán)登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何使用maven-helper插件解決jar包沖突問(wèn)題
安裝了Maven?Helper插件,只要打開(kāi)pom文件,就可以打開(kāi)該pom文件的Dependency?Analyzer視圖,這篇文章主要介紹了使用maven-helper插件解決jar包沖突,需要的朋友可以參考下2024-05-05
Java之map的常見(jiàn)用法講解與五種循環(huán)遍歷實(shí)例代碼理解
map是一組鍵值對(duì)的組合,通俗理解類似一種特殊的數(shù)組,a[key]=val,只不過(guò)數(shù)組元素的下標(biāo)是任意一種類型,而且數(shù)組的元素的值也是任意一種類型。有點(diǎn)類似python中的字典。通過(guò)"鍵"來(lái)取值,類似生活中的字典,已知索引,來(lái)查看對(duì)應(yīng)的信息2021-09-09
Springboot actuator應(yīng)用后臺(tái)監(jiān)控實(shí)現(xiàn)
這篇文章主要介紹了Springboot actuator應(yīng)用后臺(tái)監(jiān)控實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Java發(fā)送http請(qǐng)求的示例(get與post方法請(qǐng)求)
這篇文章主要介紹了Java發(fā)送http請(qǐng)求的示例(get與post方法請(qǐng)求),幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2021-01-01
解決redisTemplate向redis中插入String類型數(shù)據(jù)時(shí)出現(xiàn)亂碼問(wèn)題
這篇文章主要介紹了解決redisTemplate向redis中插入String類型數(shù)據(jù)時(shí)出現(xiàn)亂碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Java模擬計(jì)算機(jī)的整數(shù)乘積計(jì)算功能示例
這篇文章主要介紹了Java模擬計(jì)算機(jī)的整數(shù)乘積計(jì)算功能,簡(jiǎn)單分析了計(jì)算機(jī)數(shù)值進(jìn)制轉(zhuǎn)換與通過(guò)位移進(jìn)行乘積計(jì)算的原理,并結(jié)合具體實(shí)例給出了java模擬計(jì)算機(jī)成績(jī)運(yùn)算的相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
Java通過(guò)SSH連接路由器輸入命令并讀取響應(yīng)的操作方法
最近需要讀取和修改華為路由器的配置,使用Java語(yǔ)言開(kāi)發(fā),通過(guò)SSH連接,輸入命令并讀取響應(yīng),接下來(lái)通過(guò)本文給大家介紹下Java通過(guò)SSH連接路由器,輸入命令并讀取響應(yīng),需要的朋友可以參考下2024-01-01
解決Intellij IDEA 使用Spring-boot-devTools無(wú)效的問(wèn)題
下面小編就為大家?guī)?lái)一篇解決Intellij IDEA 使用Spring-boot-devTools無(wú)效的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07
使用IntelliJ IDEA調(diào)式Stream流的方法步驟
本文主要介紹了使用IntelliJ IDEA調(diào)式Stream流的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Spring配置動(dòng)態(tài)數(shù)據(jù)源實(shí)現(xiàn)讀寫(xiě)分離的方法
這篇文章主要介紹了利用Spring配置動(dòng)態(tài)數(shù)據(jù)源實(shí)現(xiàn)讀寫(xiě)分離的方法,文中通過(guò)示例代碼介紹的很詳細(xì),相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,藕需要的朋友可以一起學(xué)習(xí)學(xué)習(xí)。2017-01-01

