微信公眾號登陸 公眾號官網
寫在前面
在日常開發過程中我們難免會遇到需要網頁授權登錄獲取用戶openId的情況,隨著開發的深入我們會有很多網頁需要用到用戶的openId,而我們不可能每次都去寫一個授權登錄的接口去匹配每個網頁,為了減少我們重復的工作,本篇文章將分享一個所有網頁公共授權方案包括未配置的安全域名下的網頁。如有不足之處,可在評論區指出。
本次使用開發語言為java。使用框架springboot。
前期配置
我們都知道要想實現微信公眾號的網頁授權登錄,需在公眾號管理后臺“設置與開發”->“公眾號設置”->&34;功能設置&34;中設置網頁授權域名,如下圖所示
網頁授權域配置
但是微信官方將此域名配置限制為僅可設置兩個,那我們需要跳轉其他域名怎么辦呢,其實很簡單,我們接著往下看!
授權流程
大家都知道微信網頁授權只需要在確保微信公眾賬號擁有授權作用域(scope參數)的權限的前提下(已認證服務號,默認擁有 scope 參數中的snsapi_base和snsapi_userinfo 權限),引導關注者打開如下頁面:
http://open.weixin.qq.com/origin/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATEwechat_redirect
需要注意的是這里的授權登錄很有可能多次轉發,導致code過期的情況,因此可以加入參數connect_redirect=1告訴微信僅跳轉一次
REDIRECT_URI就為我們的用戶確認授權后 微信轉發的地址 我們要實現公共網頁的授權登錄就在這里做文章
關于scope作用域這里就不再過多地描述snsapi_base僅可以拿到戶的 openid,并且用戶是無感知的,是靜默的。snsapi_userinfo可以拿到用戶的基本信息,但不是無感知的需要用戶手動確認,特殊情況除外(對于已關注公眾號的用戶,如果用戶從公眾號的會話或者自定義菜單進入本公眾號的網頁授權頁,即使是 scope 為snsapi_userinfo,也是靜默授權,用戶無感知)。
實現代碼
@RequestMapping(&34;/common&34;)
public String authCommonUrl(String url, HttpServletRequest request)
try {
if (StringUtils.isEmpty(url)) {
return &34;/error&34;;
}
return &34;redirect:http://open.weixin.qq.com/origin/connect/oauth2/authorize?appid=&34; + environment.getProperty(&34;wechat.appId&34;)
+ &34;&redirect_uri=&34;
+ URLEncoder.encode(
environment.getProperty(&34;wechat.baseRedirectUrl&34;) + &34;/authcommonurl?url=&34; + URLEncoder.encode(url, &34;utf-8&34;),
&34;utf-8&34;)
+ &34;&response_type=code&scope=snsapi_userinfo&connect_redirect=1&state=joinwechat_redirect&34;;
} catch (Exception e) {
logger.error(&34;重定向發生異常->RedirectController.authCommon:&34; + ParamsUtils.showParams(request), e);
return &34;/error&34;;
}
}
可以看到我們將redirect_uri設置成了一個公共的獲取用戶信息的接口地址,然后在該地址上傳入我們需要最終跳轉的url,這里的url我們如果需要傳遞其他參數,也可以直接加在url上。這里我們只要保證redirect_uri在網頁授權的安全域名下,而url任意域名都可以啦。
獲取用戶信息重定向url地址
@SuppressWarnings({ &34;unchecked&34; })
@RequestMapping(value = &34;/authcommonurl&34;)
public String authCommon(String url, String code, HttpServletRequest request) {
HttpSession session = request.getSession();
try {
if (StringUtils.isEmpty(url)) {
return &34;/error&34;;
}
if (StringUtils.isEmpty(code)) {
return &34;/error&34;;
}
// 首先判斷session中是否存在用戶信息,存在則跳過以下獲取用戶信息方法,不存在繼續執行
String sessionId = session.getId();
CacheObject<JSONObject> cache = MapCacheManager.getInstance().getCache(sessionId);
JSonObject userInfoJO = cache != null ? cache.getObject() : null;
if (userInfoJO == null || StringUtils.isEmpty(userInfoJO.optString(&34;nickname&34;, &34;&34;))) {// 里面為整個網頁登錄授權過程
// 調用獲取accessToken接口 獲取accessToken
String json = HttpsUtil.httpMethodGet(getAccessTokenUrl(code), &34;UTF-8&34;);
JSonObject jsonObject = null;
try {
jsonObject = new JSonObject(json);
} catch (Exception e) {
logger.error(&34;獲取授權accesstoken轉換json異常->NotStaticAuthReturnController.authHd:&34; + json, e);
}
if (!jsonObject.has(&34;access_token&34;)) {
return &34;/error&34;;
}
String access_token = jsonObject.optString(&34;access_token&34;, &34;&34;);
String openid = jsonObject.optString(&34;openid&34;, &34;&34;);
// 得到獲取用戶信息的鏈接
// 獲取用戶信息接口 獲取用戶信息
String userInfoJson = HttpsUtil.httpMethodGet(getUserinfoUrl(access_token, openid), &34;UTF-8&34;);
try {
userInfoJO = new JSonObject(userInfoJson);
} catch (JSonException e) {
userInfoJO = new JSonObject();
logger.error(&34;獲取用戶信息轉換json異常->NotStaticAuthReturnController.authcommon:&34; + userInfoJson, e);
}
if (!userInfoJO.has(&34;nickname&34;)) {
return &34;/error&34;;
}
userInfoJO.put(&34;nickname&34;, EmojiFilter.filterEmoji(userInfoJO.optString(&34;nickname&34;, &34;&34;)));
cache = new CacheObject<>();
cache.setExpires_in(7200L);
cache.setObject(userInfoJO);
MapCacheManager.getInstance().putCache(sessionId, cache);
}
// System.out.println(&34;用戶信息:&34; + userInfoJO.toString());//輸出用戶信息 測試用
String user_openid = userInfoJO.optString(&34;openid&34;, &34;&34;);
if (StringUtils.isEmpty(user_openid)) {
return &34;/error&34;;
}
return &34;redirect:&34; + url + (url.contains(&34;?&34;) ? &34;&&34; : &34;?&34;) + &34;openId=&34; + user_openid;
} catch (Exception e) {
e.printStackTrace();
logger.error(&34;微信授權異常->NotStaticAuthReturnController.authCommonurl:&34; + ParamsUtils.showParams(request), e);
return &34;/error&34;;
}
}
這里我們作用域是snsapi_userinfo有獲取用戶的基本信息,若無需這些信息,按需求刪除代碼即可。
如有問題或不足之處可在評論區指出,覺得還行的看官動動小手幫忙點個贊吧!
祝大家健健康康,每天開開心心!