springboot 微信授權(quán)網(wǎng)頁登錄操作流程
操作流程
假設(shè)你已經(jīng)有自己的域名,因?yàn)槲⑿殴娞柡臀⑿呕卣{(diào)都需要域名
先看看官方給的文檔
根據(jù)官方文檔,主要流程如下:
(1)引導(dǎo)用戶進(jìn)入授權(quán)頁面同意授權(quán),獲取code
(2)通過code換取網(wǎng)頁授權(quán)access_token(與基礎(chǔ)支持中的access_token不同)
(3)刷新access_token(如果有需要)
(3)通過網(wǎng)頁授權(quán)access_token和openid獲取用戶基本信息
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
編寫微信授權(quán)方法和獲取用戶信息方法
二、使用步驟
獲取微信二維碼信息
代碼如下(示例):
/**
* 公眾號微信登錄授權(quán)
*/
@RequestMapping("/wxLogin")
public void wxLogin(HttpServletResponse response) throws IOException {
//這個(gè)url的域名必須在公眾號中進(jìn)行注冊驗(yàn)證,這個(gè)地址是成功后的回調(diào)地址
String backUrl = "http://7ca0c439f61c.ngrok.io/callback";//使用自己的域名
// 第一步:用戶同意授權(quán),獲取code
//請求地址 snsapi_base snsapi_userinfo
String url = "https://open.weixin.qq.com/connect/oauth2/authorize" +
"?appid=" + HttpClientUtil.APPID +
"&redirect_uri=" + URLEncoder.encode(backUrl,"utf-8") +
"&response_type=code" +
"&scope=snsapi_userinfo" +
"&state=STATE#wechat_redirect";
logger.info("forward重定向地址{" + url + "}");
//必須重定向,否則不能成功
response.sendRedirect(url);
}
備注:在前端頁面直接加載url 就可以出現(xiàn)二維碼界面了。直接用的微信的頁面,也可以根據(jù)自己的愛好進(jìn)行設(shè)計(jì)頁面
/**
* 公眾號微信登錄授權(quán)回調(diào)函數(shù)
*/
@RequestMapping("/callback")
public UserLoginRes callback(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
UserLoginRes userLoginRes = new UserLoginRes();
try{
WXUserInfoReq weixinUserInfo = new WXUserInfoReq();
/*start 獲取微信用戶基本信息*/
String code = req.getParameter("code");
//第二步:通過code換取網(wǎng)頁授權(quán)access_token
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
+ "appid=" + HttpClientUtil.APPID
+ "&secret=" + HttpClientUtil.APPSECRET
+ "&code=" + code
+ "&grant_type=authorization_code";
System.out.println(url);
String result = HttpClientUtil.doGet(url);
JSONObject jsonObject = JSON.parseObject(result);
/*
{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
*/
String openid = jsonObject.getString("openid");
String access_token = jsonObject.getString("access_token");
//第三步驗(yàn)證access_token是否失效;
String chickUrl = "https://api.weixin.qq.com/sns/auth?access_token="
+ access_token + "&openid=" + openid;
String resultInfo = HttpClientUtil.doGet(chickUrl);
JSONObject chickuserInfo = JSON.parseObject(resultInfo);
System.out.println(chickuserInfo.toString());
if (!"0".equals(chickuserInfo.getString("errcode"))) {
String refreshInfo1 = HttpClientUtil.doGet(chickUrl);
JSONObject refreshInfo = JSON.parseObject(refreshInfo1);
/*
{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE" }
*/
access_token = refreshInfo.getString("access_token");
}
// 第四步:拉取用戶信息
String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token
+ "&openid=" + openid
+ "&lang=zh_CN";
JSONObject userInfo = JSON.parseObject(HttpClientUtil.doGet(infoUrl));
/*
{ "openid":" OPENID",
"nickname": NICKNAME,
"sex":"1",
"province":"PROVINCE"
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
*/
System.out.println(userInfo.getString("openid") + ":" + userInfo.getString("nickname") +":" + userInfo.getString("sex"));
}catch (Exception e){
e.printStackTrace();
userLoginRes.setResult("NO");
userLoginRes.setRtnErrId("ERROR");
userLoginRes.setRtnErrMsg(e.getMessage());
}
return userLoginRes;
}
使用到的HttpClientUtil工具類
代碼如下(示例):
public class HttpClientUtil {
//appid、secret為自己公眾號平臺的appid和secret
public static final String APPID="xxxxxxx";
public static final String APPSECRET ="xxxxxxx";
public static String doGet(String url, Map<String, String> param) {
// 創(chuàng)建Httpclient對象
CloseableHttpClient httpclient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
HttpGet httpGet = null;
try {
// 創(chuàng)建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 創(chuàng)建http GET請求
httpGet = new HttpGet(uri);
httpGet.setHeader("Host", "api.weixin.qq.com");
httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
httpGet.setHeader("Accept", "text/html, application/xhtml+xml, */*");
httpGet.setHeader("Accept-Encoding", "gzip, deflate, br");
httpGet.setHeader("Connection", "keep-alive");
httpGet.setHeader("Accept-Language", "zh-CN");
httpGet.setHeader("Cache-Control", "no-cache");
// 執(zhí)行請求
response = httpclient.execute(httpGet);
// 判斷返回狀態(tài)是否為200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpGet.releaseConnection();
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doGet(String url) {
return doGet(url, null);
}
public static String doPost(String url, Map<String, String> param) {
// 創(chuàng)建Httpclient對象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 創(chuàng)建Http Post請求
HttpPost httpPost = new HttpPost(url);
// 創(chuàng)建參數(shù)列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模擬表單
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
// 執(zhí)行http請求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doPost(String url) {
return doPost(url, null);
}
public static String doPostJson(String url, String json) {
// 創(chuàng)建Httpclient對象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 創(chuàng)建Http Post請求
HttpPost httpPost = new HttpPost(url);
// 創(chuàng)建請求內(nèi)容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 執(zhí)行http請求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doGetStr(String httpurl) {
HttpURLConnection connection = null;
InputStream is = null;
BufferedReader br = null;
String result = null;// 返回結(jié)果字符串
try {
// 創(chuàng)建遠(yuǎn)程url連接對象
URL url = new URL(httpurl);
// 通過遠(yuǎn)程url連接對象打開一個(gè)連接,強(qiáng)轉(zhuǎn)成httpURLConnection類
connection = (HttpURLConnection) url.openConnection();
// 設(shè)置連接方式:get
connection.setRequestMethod("GET");
// 設(shè)置連接主機(jī)服務(wù)器的超時(shí)時(shí)間:15000毫秒
connection.setConnectTimeout(15000);
// 設(shè)置讀取遠(yuǎn)程返回的數(shù)據(jù)時(shí)間:60000毫秒
connection.setReadTimeout(60000);
//設(shè)置請求頭
connection.setRequestProperty("Host", "api.weixin.qq.com");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
connection.setRequestProperty("Accept", "text/html, application/xhtml+xml, */*");
connection.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
connection.setRequestProperty("Connection", "keep-alive");
connection.setRequestProperty("Accept-Language", "zh-CN");
connection.setRequestProperty("Cache-Control", "no-cache");
// 發(fā)送請求
connection.connect();
// 通過connection連接,獲取輸入流
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
// 封裝輸入流is,并指定字符集
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
// 存放數(shù)據(jù)
StringBuffer sbf = new StringBuffer();
String temp = null;
while ((temp = br.readLine()) != null) {
sbf.append(temp);
sbf.append("\r\n");
}
result = sbf.toString();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 關(guān)閉資源
if (null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
connection.disconnect();// 關(guān)閉遠(yuǎn)程連接
}
return result;
}
}
最后根據(jù)實(shí)際業(yè)務(wù)處理用戶登錄
//3.根據(jù)uuid查詢用戶是否存在,如果存在直接登錄。如果不存在則自動注冊,在登錄
UserInfoModel userInfoByWechat = iUserDao.getUserInfoByWechat(userInfoStr.get("unionid").toString());
if (userInfoByWechat != null) {
return ReturnMessage.success(0,"獲取成功",userInfoByWechat);
}
//4.數(shù)據(jù)庫添加用戶信息
String username = userInfoStr.get("nickname").toString();
String unionid = userInfoStr.get("unionid").toString();
UserInfoBean userInfoBean = new UserInfoBean();
userInfoBean.setUuid(unionid);
userInfoBean.setUsername(username);
// 微信登錄
userInfoBean.setStatus(2);
iUserDao.insertUser(userInfoBean);
//5.根據(jù)uuid查詢新注冊的用戶信息
UserInfoModel userInfoModel= iUserDao.getUserInfoByWechat(unionid);
if (userInfoModel == null) {
return ReturnMessage.fail(400,"用戶添加失敗,請重新操作");
}
到此這篇關(guān)于springboot 微信授權(quán)網(wǎng)頁登錄操作流程的文章就介紹到這了,更多相關(guān)springboot 微信授權(quán)登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot項(xiàng)目中實(shí)現(xiàn)微信小程序登錄案例(最新推薦)
- SpringBoot整合Mybatis-Plus實(shí)現(xiàn)微信注冊登錄的示例代碼
- 微信小程序使用uni-app和springboot實(shí)現(xiàn)一鍵登錄功能(JWT鑒權(quán))
- springboot實(shí)現(xiàn)微信掃碼登錄的項(xiàng)目實(shí)踐
- springboot+jwt+微信小程序授權(quán)登錄獲取token的方法實(shí)例
- 詳解SpringBoot如何實(shí)現(xiàn)整合微信登錄
- 一篇文章帶你入門Springboot整合微信登錄與微信支付(附源碼)
- SpringBoot實(shí)現(xiàn)微信掃碼登錄的示例代碼
相關(guān)文章
在SpringBoot中通過jasypt進(jìn)行加密解密的方法
今天小編就為大家分享一篇關(guān)于在SpringBoot中通過jasypt進(jìn)行加密解密的方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01
IDEA手動添加junit4時(shí)出現(xiàn)的問題與解決方法
這篇文章主要給大家介紹了關(guān)于IDEA手動添加junit4時(shí)出現(xiàn)的問題與解決方法,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
基于java Springboot實(shí)現(xiàn)教務(wù)管理系統(tǒng)詳解
這篇文章主要介紹了Java 實(shí)現(xiàn)簡易教務(wù)管理系統(tǒng)的代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08
SpringBoot+Spring Security基于內(nèi)存用戶認(rèn)證的實(shí)現(xiàn)
本文介紹了SpringBoot+Spring Security基于內(nèi)存用戶認(rèn)證的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11
IDEA SpringBoot:Cannot resolve configuration&
這篇文章主要介紹了IDEA SpringBoot:Cannot resolve configuration property配置文件問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07

