SoringCloud(四) - 微信獲取用戶信息

来源:https://www.cnblogs.com/xiaoqigui/archive/2022/10/30/16841694.html
-Advertisement-
Play Games

1、項目介紹 2、微信公眾平臺 和 微信開放文檔 2.1 微信公眾平臺 2.1.1 網址鏈接 https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index 2.1.2 測試號信息 2.1.3 微信 ...


1、項目介紹

2、微信公眾平臺 和 微信開放文檔

2.1 微信公眾平臺

2.1.1 網址鏈接

https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

2.1.2 測試號信息

2.1.3 微信掃描關註測試公眾號

2.1.4 授權回調頁面功能變數名稱

2.1.4.1 網頁服務->網頁賬號->修改

2.1.4.2 填寫 授權回調頁面功能變數名稱

2.1.4.3 內網穿透 NATAPP
2.1.4.3.1 使用教程
NATAPP1分鐘快速新手圖文教程: https://natapp.cn/article/natapp_newbie

下載: https://natapp.cn/#download

使用本地配置文件config.ini: https://natapp.cn/article/config_ini
2.1.4.3.2 authtoken

2.1.4.3.3 授權回調頁面功能變數名稱

2.2 微信開放文檔

2.2.1 網址鏈接

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#2

2.2.2 官方 基本步驟教程

1 第一步:用戶同意授權,獲取code

2 第二步:通過 code 換取網頁授權access_token

3 第三步:刷新access_token(如果需要)

4 第四步:拉取用戶信息(需 scope 為 snsapi_userinfo)

5 附:檢驗授權憑證(access_token)是否有效

3、http請求工具類 HttpClient4Util

HttpClient4Util 用來發http請求;

https://www.cnblogs.com/xiaoqigui/p/16839536.html

4、配置文件 和 配置類

4.1 配置文件

application.yml

#埠
server:
  port: 8096

# 自定義微信授權信息
wechat:
  auth:
    app-id: wxd4e20add67******   #  appID
    app-secret: a21e97d21d0d6ce408b7a6c******  # appsecret
    code-uri: https://open.weixin.qq.com/connect/oauth2/authorize  # 請求微信官方獲取用戶授權code 的請求地址
    redirect-uri: http://******.natappfree.cc/wechat/auth/codeBack # 微信官方返回  用戶授權code 的回調地址
    access-token-uri: https://api.weixin.qq.com/sns/oauth2/access_token # 根據微信回調的code值,請求微信官方獲取用戶access_token  的請求地址
    user-info-uri: https://api.weixin.qq.com/sns/userinfo #根據用戶的 accessToken 和  openId 拉取用戶信息  的請求地址

4.2 配置類

//自定義微信授權參數信息配置類
@Data
@Component
@ConfigurationProperties(prefix = "wechat.auth")
public class WeChatAuthConfig {
    /*
        應用id
     */
    private String appId;
    /*
        應用密鑰
     */
    private String appSecret;
    /*
        請求獲取code的地址
     */
    private String codeUri;
    /*
        微信官方回調code的地址
     */
    private String redirectUri;
    /**
     * 微信官方獲取access_token地址
     */
    private String accessTokenUri;
    /*
        微信官方獲取userInfo地址
     */
    private String userInfoUri;

}

5、server 層

5.1 微信授權的業務介面

/**
 * Created On : 28/10/2022.
 * <p>
 * Author : huayu
 * <p>
 * Description: 微信授權的業務介面
 */
public interface WeChatAuthService {

    //生成請求微信官方獲取用戶授權code的請求地址
    
    //根據微信回調的code值,請求微信官方獲取用戶access_token
    
    //根據用戶的 accessToken 和  openId 拉取用戶信息

}

5.1.1 生成請求微信官方獲取用戶授權code的請求地址

/**
* @author : huayu
* @date   : 28/10/2022
* @param  : []
* @return : java.lang.String
* @description : 生成請求微信官方獲取用戶授權code的請求地址
*/

String generateWeChatAuthCodeUrl();

5.1.2 根據微信回調的code值,請求微信官方獲取用戶access_token

/**
* @author : huayu
* @date   : 28/10/2022
* @param  : [wechatAuthCode]
* @return : java.lang.String
* @description : 根據微信回調的code值,請求微信官方獲取用戶access_token
*/
String getAccessTokenFromWechatUseCode(String wechatAuthCode);

5.1.3 根據用戶的 accessToken 和 openId 拉取用戶信息

/**
* @author : huayu
* @date   : 28/10/2022
* @param  : [accessToken, openId]
* @return : java.lang.String
* @description : 根據用戶的 accessToken 和  openId 拉取用戶信息
*/
String getUserInfoFromWechatUseAccessToken(String accessToken,String openId);

5.2 微信授權的業務介面 實現類

/**
 * Created On : 28/10/2022.
 * <p>
 * Author : huayu
 * <p>
 * Description: 微信授權的業務介面 實現類
 */
@Service
@Slf4j
public class WeChatAuthServiceImpl implements WeChatAuthService{

    //註入 http請求工具類
    @Autowired
    private WeChatAuthConfig weChatAuthConfig;
	
    //生成請求微信官方獲取用戶授權code的請求地址
    
    //根據微信回調的code值,請求微信官方獲取用戶access_token
    
    //根據用戶的 accessToken 和  openId 拉取用戶信息

}

5.2.1 生成請求微信官方獲取用戶授權code的請求地址

/**
* @author : huayu
* @date   : 29/10/2022
* @param  : []
* @return : java.lang.String
* @description : 生成請求微信官方獲取用戶授權code的請求地址
*/
@Override
public String generateWeChatAuthCodeUrl() {

    //微信官方引導用戶打開授權頁面,獲取code的完整路徑
    //https://open.weixin.qq.com/connect/oauth2/authorize
    // ?appid=APPID
    // &redirect_uri=REDIRECT_URI
    // &response_type=code
    // &scope=SCOPE
    // &state=STATE
    // #wechat_redirect
    //尤其註意:由於授權操作安全等級較高,所以在發起授權請求時,微信會對授權鏈接做正則強匹配校驗,如果鏈接的參數順序不對,授權頁面將無法正常訪問

    //生成請求衛星官方獲取用戶code的完整地址
    StringBuilder weCharAuthCodeUrl = new StringBuilder(weChatAuthConfig.getCodeUri());
    weCharAuthCodeUrl.append("?appid=").append(weChatAuthConfig.getAppId())
        .append("&redirect_uri=").append(weChatAuthConfig.getRedirectUri())
        .append("&response_type=code")
        //&scope=snsapi_userinfo&state=STATE
        .append("&scope=").append("snsapi_userinfo")
        .append("&state=").append("kh96_wechat_auth")
        .append("#wechat_redirect");

    log.info("------ 請求微信官方授權網站地址:{}  ------",weCharAuthCodeUrl.toString());

    //返貨完整的請求地址
    return weCharAuthCodeUrl.toString();

}

5.2.2 根據微信回調的code值,請求微信官方獲取用戶access_token

/**
* @author : huayu
* @date   : 29/10/2022
* @param  : [wechatAuthCode]
* @return : java.lang.String
* @description : 根據微信回調的code值,請求微信官方獲取用戶access_token
*/
@Override
public String getAccessTokenFromWechatUseCode(String wechatAuthCode) {
    // 尤其註意:由於公眾號的 secret 和獲取到的access_token安全級別都非常高,必須只保存在伺服器,不允許傳給客戶端。
    // 請求方法:獲取 code 後,請求以下鏈接獲取access_token:
    // https://api.weixin.qq.com/sns/oauth2/access_token
    // ?appid=APPID
    // &secret=SECRET
    // &code=CODE
    // &grant_type=authorization_code

    // 封裝根據code,請求微信官方獲取access_token的完整地址
    StringBuilder accessTokenUrl = new StringBuilder(weChatAuthConfig.getAccessTokenUri());
    accessTokenUrl.append("?appid=").append(weChatAuthConfig.getAppId())
        .append("&secret=").append(weChatAuthConfig.getAppSecret())
        .append("&code=").append(wechatAuthCode)
        .append("&grant_type=authorization_code");

    log.info("------ 根據code,請求微信官方獲取access_token的完整地址:{} ------", accessTokenUrl.toString());

    // 根據code,請求微信官方獲取access_token,返回結果是同步返回的,不再是非同步回調
    // 請求是伺服器內部發起的,也就是說:在程式中,要根據上面完整的請求地址,主動發送請求到微信官方,介面同步會返回一個json格式的字元串結果,程式內要解析獲取的結果

    // 程式內主動發起http請求,獲取access_token
    return HttpClient4Util.getResponse4GetAsString(accessTokenUrl.toString(), "utf-8");
}

5.2.3 根據用戶的 accessToken 和 openId 拉取用戶信息

/**
* @author : huayu
* @date   : 29/10/2022
* @param  : [accessToken, openId]
* @return : java.lang.String
* @description : 根據用戶的 accessToken 和  openId 拉取用戶信息
*/
@Override
public String getUserInfoFromWechatUseAccessToken(String accessToken, String openId) {

    // 如果網頁授權作用域為snsapi_userinfo,則此時開發者可以通過access_token和 openid 拉取用戶信息了。
    // http:GET(請使用 https 協議):
    // https://api.weixin.qq.com/sns/userinfo
    // ?access_token=ACCESS_TOKEN
    // &openid=OPENID
    // &lang=zh_CN

    // 封裝根據accessToken和openId,請求微信官方獲取用戶信息詳情地址
    StringBuilder userInfoUrl = new StringBuilder(weChatAuthConfig.getUserInfoUri());
    userInfoUrl.append("?access_token=").append(accessToken)
        .append("&openid=").append(openId)
        .append("&lang=zh_CN");
    log.info("------ 根據access_token,請求微信官方獲取userinfo的完整地址:{} ------", userInfoUrl.toString());

    // 程式內主動發起http請求,獲取用戶詳情
    return HttpClient4Util.getResponse4GetAsString(userInfoUrl.toString(), "utf-8");
}

6、controller 層

/**
 * Created On : 28/10/2022.
 * <p>
 * Author : huayu
 * <p>
 * Description: 測試微信授權登錄操作入口
 */
//@SuppressWarnings("all")
@Slf4j
@RestController
@RequestMapping("/wechat/auth")
public class WeChatAuthController {

    //註入service層實現類
    @Autowired
    private WeChatAuthService weChatAuthService;

}

6.1 獲取請求微信官方貨物code的完整地址,用戶訪問該地址

/**
* @author : huayu
* @date   : 28/10/2022
* @param  : []
* @return : com.kgc.scd.uitl.RequestResult<java.lang.String>
* @description :  獲取請求微信官方貨物code的完整地址,用戶訪問該地址,可以進行授權操作(把地址交給前端生成二維碼給用戶掃碼,或者後端生成)
*/
@GetMapping("/codeUrl")
public RequestResult<String> codeUrl(){

    //調用業務介面,獲取完整用戶授權訪問的地址
    return ResultBuildUtil.success(weChatAuthService.generateWeChatAuthCodeUrl());

}

6.2 獲取用戶詳情信息

用戶授權後,接收微信官方非同步回調請求,獲取用戶授權的code:(code,state)
	1.通過 code 換取網頁授權access_token
	2.拉取用戶信息(需 scope 為 snsapi_userinfo)
	3.介面返回用戶詳情信息
/**
* @author : huayu
* @date   : 28/10/2022
* @param  : []
* @return : com.kgc.scd.uitl.RequestResult<java.util.Map<java.lang.String,java.lang.Object>>
* @description : 接收微信官方非同步回調請求,獲取用戶授權的code
* 流程:用戶先根據上一步返回請求地址,進行授權操作,如果用戶統一授權,微信官方自動根據上一步請求帶過去的回調地址redirectUri,進行結果回調
*/
@RequestMapping("/codeBack")
public RequestResult<Map<String, Object>> codeBack(HttpServletRequest request){

    // 用戶同意授權後,如果用戶同意授權,頁面將跳轉至 redirect_uri/?code=CODE&state=STATE。
    // code說明:code作為換取access_token的票據,每次用戶授權帶上的 code 將不一樣,code只能使用一次,5分鐘未被使用自動過期。

    // 從官方回調的請求中,獲取用戶授權後的code參數值
    String wechatAuthCode = request.getParameter("code");
    // 從官方回調的請求中,獲取用戶授權時的自定義參數state
    String wechatAuthState = request.getParameter("state");

    log.info("------ 微信授權後,官方非同步回調結果:code={},state={} ------", wechatAuthCode, wechatAuthState);

    // 定義介面返回集合對象
    Map<String, Object> resultMap = new HashMap<>();

    // 參數非空校驗
    if(StringUtils.isBlank(wechatAuthCode)){
        resultMap.put("msg", "授權code為空!");
        return ResultBuildUtil.fail(resultMap);
    }

    // 1. 調用業務介面,通過 code 換取網頁授權access_token
    String accessTokenJson = weChatAuthService.getAccessTokenFromWechatUseCode(wechatAuthCode);
    log.info("------ 通過 code 換取網頁授權access_token返回結果:{} ------", accessTokenJson);

    // 正確時返回的 JSON 數據包如下:
    // {"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE"}
    // 錯誤時返回的 JSON 數據包如下:
    // {"errcode":40029,"errmsg":"invalid code"}

    // 解析返回的json數據
    JSONObject accessTokenJsonObj = JSON.parseObject(accessTokenJson);

    // 判斷獲取access_token結果是否正確,如果錯誤,直接結束,如果正確,獲取對應的access_token
    if(StringUtils.isNotBlank(accessTokenJsonObj.getString("errcode"))){
        resultMap.put("wxCode", accessTokenJsonObj.getString("errcode"));
        resultMap.put("wxMsg", accessTokenJsonObj.getString("errmsg"));
        return ResultBuildUtil.fail(resultMap);
    }

    // 2. 拉取用戶信息(需 scope 為 snsapi_userinfo)
    // 根據上一步返回json,獲取拉取用戶信息憑證-access_token和用戶唯一標識-openid
    String accessToken = accessTokenJsonObj.getString("access_token");
    String openId = accessTokenJsonObj.getString("openid");

    //  調用業務介面,通過access_token和openId,拉取用戶詳情
    String userInfoJson = weChatAuthService.getUserInfoFromWechatUseAccessToken(accessToken, openId);
    log.info("------ 通過access_token和openId,拉取用戶詳情:{} ------", userInfoJson);

    // 3.介面返回用戶詳情信息
    resultMap.put("userInfo", userInfoJson);

    // TODO 獲取成功用戶信息後,系統要完成靜默註冊-把用戶信息註冊到系統數據中,存儲用戶的頭像,昵稱,openId信息,並給系統用戶表增加其它的基本信息

    //返回用戶詳情
    return ResultBuildUtil.success(resultMap);
}

7、測試

7.1 生成請求微信官方獲取用戶授權code的請求地址

7.2 獲取用戶信息





您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 在併發編程中,當多個線程同時訪問同一個共用的可變變數時,會產生不確定的結果,所以要編寫線程安全的代碼,其本質上是對這些可變的共用變數的訪問操作進行管理。導致這種不確定結果的原因就是可見性、有序性和原子性問題,Java 為解決可見性和有序性問題引入了 Java 記憶體模型,使用互斥方案(其核心實現 ...
  • 前言 最近在調研 小米開放平臺 API 的能力,發現能力支持的實在有點少,沒辦法只能另闢蹊徑去逆向 Consule UI 的能力。 逆向工程最重要解決的就是“認證”。有沒有辦法自動登錄鑒權,或者使用一個長久可靠、可續期的 token,直接決定了該 Consule UI 是否可逆向。 逆向工程-認證 ...
  • 我們都知道,我們寫的Java程式需要先經過編譯,生成了.class文件(位元組碼文件)。然而,電腦並不能直接解釋.class文件裡面的內容,這時候就需要一個能載入、解釋.class文件並且能按.class文件里的內容進行處理的一個東西--JVM。 JVM,就是Java虛擬機。它是一種規範,有針對不同 ...
  • Count15 module top_module ( input clk, input reset, // Synchronous active-high reset output [3:0] q); always@(posedge clk) begin if(reset) q <= 4'd0; ...
  • 2022-10-30 連接資料庫的搭建環境 一、搭建環境 ①導入jar包(資料庫驅動包、資料庫連接池、DBUtils) jar包有:commons-dbutils-1.4.jar、 druid-1.0.9.jar 、mysql-connector-java-8.0.19.jar。 方式:在創建的“W ...
  • 本篇文章,將從 0 淺入,從什麼是哈希表講起,然後再說 Java 是怎樣實現哈希表的。整個梳理過程,將通過源碼這個第一手的資料進行梳理分析,吸收知識、解決疑問,一步一步進行梳理,如果你是對 HashMap 懵懵懂懂的同學,那麼歡迎跟著我的節奏一起來梳理!全文1萬2000多字,歡迎慢慢食用! ...
  • JavaScript01 官方文檔 http://www.w3school.com.cn/js/index.asp 基本說明: JavaScript能改變html內容,能改變html屬性,能改變html樣式(css),能完成頁面的數據驗證。 例子 <!DOCTYPE html> <html lang ...
  • SpringBoot 階段測試 1 1、使用JDK8新語法完成下列集合練習: 1.1 List中有1,2,3,4,5,6,7,8,9幾個元素要求; (1) 將奇、偶數分別匯聚成一個List //初始化集合 List<Integer> numList = new ArrayList<>(); //批量 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...