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 獲取用戶資訊

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/523157.html
標籤:其他
