OpenID是用戶在某一個公眾號的唯一標識,用戶不同公眾號的的OpenID是不一樣的。在開發的時候,我們有時需要獲取用戶的OpenID。本文將介紹以下內容:“用戶頁面授權HTML代碼”、“調用服務器后端接口的js代碼”、“用戶靜默授權后端接口”、“微信服務器回調我們的服務器接口”、“獲取微信服務器返回的信息”。
1、用戶頁面授權HTML代碼。
設計一個用戶點擊授權的前端頁面:
<div id="loginMain">
<div id="loginInfomation" class="layui-form">
<h2>歡迎登錄博銷寶管理后台</h2>
<div class="layui-form-item">
<label class="layui-form-label"><strong class="requiredField">*</strong>公司編號:</label>
<div class="layui-input-block">
<input type="text" class="layui-input" name="${Staff.FIELD_NAME_companySN}" value="" lay-verify="required|checkCompanySN" placeholder="請輸入公司編號" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><strong class="requiredField">*</strong>手機號碼:</label>
<div class="layui-input-block">
<input type="text" class="layui-input" name="${Staff.FIELD_NAME_phone}" value="" lay-verify="required|checkPhone" maxlength="11" placeholder="請輸入手機號碼" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><strong class="requiredField">*</strong>密碼:</label>
<div class="layui-input-block">
<input type="password" class="layui-input" name="${Staff.FIELD_NAME_salt}" value="" lay-verify="required|checkPassword" placeholder="請輸入密碼" />
</div>
</div>
<input type="hidden" value="${identify}" name="identify">
<input type="hidden" value="${ID}" name="ID">
<button class="layui-btn layui-btn-lg layui-btn-normal" lay-submit lay-filter="wxLogin">登錄</button>
</div>
</div>
2、調用服務器后端接口的js代碼。
//登錄系統
form.on("submit(wxLogin)", function(data){
var indexLoading = layer.load(1);
var info = data.field;
$.ajax({
url: wxLogin_url,
type: 'get',
async: true,
dataType: "json",
data: info,
success: function succFunction(data) {
console.log(data);
layer.close(indexLoading);
if (data) {
if (data.ERROR != "EC_NoError") {
if (data.msg) {
layer.msg("<span style='font-size: 0.2rem;'>" + data.msg + "</span>");
} else {
layer.msg("<span style='font-size: 0.2rem;'>登錄失敗</span>");
}
} else {
switch (info.identify) {
case "purchasingOrder":
window.location.href = "../wx/purchasingOrderApproval.bx?ID=" + info.ID;
break;
case "unSalableCommodity":
window.location.href = "../wx/unsalableCommodity.bx";
break;
default:
console.log("未定義的標識符");
break;
}
}
} else {
layer.msg("<span style='font-size: 0.2rem;'>登錄失敗</span>");
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
layer.close(indexLoading);
layer.msg(XMLHttpRequest.status + ":" + XMLHttpRequest.statusText);
}
});
})
3、用戶靜默授權后端接口。
用戶授權后,我們才能請求微信服務器獲取用戶信息。根據訪問code的地址GET_CODE_URL,公眾號賬號appid和我們設置的回調接口callback_url生成url並訪問微信服務器:
/** 用戶請求頁面(snsapi_userinfo頁面授權) */
@RequestMapping(value = "/wxLogin") // ...
public void toGetAuthentication(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (!canCallCurrentAction(request.getSession(), BaseAction.EnumUserScope.ANYONE.getIndex())) {
logger.debug("無權訪問本Action");
return;
}
logger.info("用戶訪問服務器!!!網頁授權!!!");
// 檢查Cookie值是否存在
// checkCookie(request, response);// ...可能在這個函數里面已經跳轉,下面的代碼不需要再跳轉
String backUrl = callback_url;
String url = String.format(GET_CODE_URL, PUBLIC_ACCOUNT_APPID, URLEncoder.encode(backUrl, "UTF-8"), "snsapi_userinfo");// ...
// 頁面重定向
response.sendRedirect(url);
}
4、微信服務器回調我們的服務器接口。
callBack接口是我們在用戶授權的時候指定的回調接口:
/** 靜默授權后,微信會回調本ACTION,獲取用戶OpenId 參考微信官方文檔:XXXXXXX */
@RequestMapping(value = "/callBack")
public String getOpenId(HttpServletRequest request, HttpServletResponse response, ModelMap mm) throws ClientProtocolException, IOException, ServletException {
if (!canCallCurrentAction(request.getSession(), BaseAction.EnumUserScope.ANYONE.getIndex())) {
logger.debug("無權訪問本Action");
return null;
}
……
獲取微信返回的code,用code獲取openid:
logger.info("callBack===接受到微信服務器發來的請求!!!");
String code = request.getParameter(BaseWxModel.WX_CODE);// 微信會返回code值,用code獲取openid
根據獲取用戶openID的地址GET_OPENID_URL,公眾號賬號PUBLIC_ACCOUNT_APPID,公眾號密碼PUBLIC_ACCOUNT_SECRET和code拼接請求URL:
// 1.拼接URL
String url = String.format(GET_OPENID_URL, PUBLIC_ACCOUNT_APPID, PUBLIC_ACCOUNT_SECRET, code); // ...
向微信端發送請求,並返回JSON數據:
JSONObject jsonObject = WxUtils.getDataFromWxServer(url);
/** 通用函數。 向微信服務器發送Get請求,返回JSON數據。 */
public static JSONObject getDataFromWxServer(String url) {
HttpClient httpClient = HttpClientBuilder.create().build();
try {
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet);// 接收client執行的結果
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "UTF-8");
return JSONObject.fromObject(result);
} else {
logger.error("向微信服務器發送Get請求發生錯誤!");
return null;
}
} catch (Exception e) {
logger.error("向微信服務器發送Get請求發生錯誤:" + e.getMessage());
return null;
}
}
5、獲取微信服務器返回的信息。
判斷返回的錯誤碼信息:
if (jsonObject.get(BaseWxModel.WX_ERRMSG) != null) {
request.setAttribute("msg", "授權失敗!!!請重新登錄!");
response.sendRedirect("/WEB-INF/wx/wx_loginFinished.jsp");
}
獲取微信端返回的openID數據:
String openid = jsonObject.getString(WxUser.field.getFIELD_NAME_openid()); // 用戶唯一標識
String token = jsonObject.getString(WxAccessToken.field.getFIELD_NAME_accessToken()); // 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同
String expires_in = request.getParameter(WxAccessToken.field.getFIELD_NAME_accessToken()); // access_token接口調用憑證超時時間,單位(秒)
String refresh_token = request.getParameter(BaseWxModel.WX_REFRESH_TOKEN); // 用戶刷新access_token