微信小程式+java後臺實現登入(java操作)
阿新 • • 發佈:2018-12-11
登入,在微信小程式上面稱為當一個使用者使用該小程式,進入到小程式中,我們拿到該使用者的資訊,進行一系列的操作,並記錄下來。 微信小程式與java介面實現登入操作,大致思路如下: 1.微信小程式端通過呼叫對應的api,將對應的變數傳入後臺(code、iv、encryptedData)。 2. 後臺首先使用code,按照微信伺服器端的傳參規定,拿到對應的值,sessionKey 以及 openid 。 3. 呼叫成功之後,拿到openId 判斷該使用者是否為第一次進入小程式,如果是,不入庫,相反,需要將使用者的基本資訊入庫,基本資訊從何來,就需要使用到微信小程式傳入到後臺的另二個變數,通過解密使用者敏感資訊得到,將其資訊入庫。 4. 入庫成功後,將對應的資訊放入到快取中,我選擇的快取為redis,設定對應的過期時間,最後將生成的uuid 放入到map中,將其返回小程式中。
對應程式碼如下:
1.呼叫微信伺服器端得到返回值;
String code = reqMap.get("code"); String url = MapUtils.getString(configProperties, "url");//請求的地址 String appId = MapUtils.getString(configProperties, "appId");//開發者對應的AppID String appSecret = MapUtils.getString(configProperties, "appSecret");//開發者對應的AppSecret String grant_type = MapUtils.getString(configProperties, "grant_type"); Map<String, Object> map = new HashMap<>(); map.put("appid",appId); map.put("secret",appSecret); map.put("js_code",code); map.put("grant_type",grant_type); //呼叫微信介面獲取openId使用者唯一標識 String wxReturnValue = UrlUtil.sendPost(url, map);
2.將其轉化map,進行入庫操作;
Map<String,Object> tempMap = JsonUtils.convertJson2Object(post, Map.class); if(tempMap.containsKey("errcode")){ String errcode = tempMap.get("errcode").toString(); log.info("微信返回的錯誤碼",errcode); }else if(tempMap.containsKey("session_key")){ log.info("呼叫微信成功"); //開始處理userInfo String openid = tempMap.get("openid").toString(); WxUser wxuser = new WxUser(); wxuser.setWopenId(openid); //先查詢openId存在不存在,存在不入庫,不存在就入庫 List<WxUser> wxUserList = wxUserMapper.selectOpenIdNum(wxuser); String session_key = ""; if(wxUserList != null && wxUserList.size() > 0){ log.info("openId已經存在,不需要插入"); }else{ log.info("openId不存在,插入資料庫"); //對encryptedData使用者資料加解密 String encryptedData = reqMap.get("encryptedData"); String iv = reqMap.get("iv"); session_key = tempMap.get("session_key").toString(); Map<String,String> userMap = getUserInfo(encryptedData, session_key, iv); String nickName = userMap.get("nickName"); String avatarUrl = userMap.get("avatarUrl"); String gender = String.valueOf(userMap.get("gender")); String province = userMap.get("province"); String city = userMap.get("city"); String country = userMap.get("country"); //建立物件,將資料插入資料庫中 WxUser newUser = new WxUser(); String wxUserId = UUID.randomUUID().toString().replaceAll("-", "");//使用者id newUser.setWid(wxUserId); newUser.setWopenId(openid); newUser.setWnickName(nickName); newUser.setWavatarUrl(avatarUrl); newUser.setWgender(gender); newUser.setWprovince(province); newUser.setWcity(city); newUser.setWcountry(country); Integer count1 = wxUserMapper.insertWxUser(newUser); } } //判斷快取資訊,如果存在去除掉舊的快取資訊,快取新的對應的資料。 //生成對應的uuid 將其建立起關係,返回即可。
3.補全上面提到的工具類。
/**
* 解密使用者敏感資料獲取使用者資訊
*
* @param sessionKey 資料進行加密簽名的金鑰
* @param encryptedData 包括敏感資料在內的完整使用者資訊的加密資料
* @param iv 加密演算法的初始向量
* @return
* */
public static Map<String,String> getUserInfo(String encryptedData, String sessionKey, String iv) {
// 被加密的資料
byte[] dataByte = Base64.decode(encryptedData);
// 加密祕鑰
byte[] keyByte = Base64.decode(sessionKey);
// 偏移量
byte[] ivByte = Base64.decode(iv);
try {
// 如果金鑰不足16位,那麼就補足. 這個if 中的內容很重要
int base = 16;
if (keyByte.length % base != 0) {
int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
byte[] temp = new byte[groups * base];
Arrays.fill(temp, (byte) 0);
System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
keyByte = temp;
}
// 初始化
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
parameters.init(new IvParameterSpec(ivByte));
cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
byte[] resultByte = cipher.doFinal(dataByte);
if (null != resultByte && resultByte.length > 0) {
String result = new String(resultByte, "UTF-8");
Map<String, String> userMap = JsonUtils.convertJson2Object(result, Map.class);
return userMap;
}
} catch (NoSuchAlgorithmException e) {
log.error(e.getMessage(), e);
} catch (NoSuchPaddingException e) {
log.error(e.getMessage(), e);
} catch (InvalidParameterSpecException e) {
log.error(e.getMessage(), e);
} catch (IllegalBlockSizeException e) {
log.error(e.getMessage(), e);
} catch (BadPaddingException e) {
log.error(e.getMessage(), e);
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage(), e);
} catch (InvalidKeyException e) {
log.error(e.getMessage(), e);
} catch (InvalidAlgorithmParameterException e) {
log.error(e.getMessage(), e);
} catch (NoSuchProviderException e) {
log.error(e.getMessage(), e);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
UrlUtils工具類:
/**
* 向指定 URL 傳送POST方法的請求
*
* @param url 傳送請求的 URL
* @param paramMap 請求引數
* @return 所代表遠端資源的響應結果
*/
public static String sendPost(String url, Map<String, ?> paramMap) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
String param = "";
Iterator<String> it = paramMap.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
param += key + "=" + paramMap.get(key) + "&";
}
try {
URL realUrl = new URL(url);
// 開啟和URL之間的連線
URLConnection conn = realUrl.openConnection();
// 設定通用的請求屬性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 傳送POST請求必須設定如下兩行
conn.setDoOutput(true);
conn.setDoInput(true);
// 獲取URLConnection物件對應的輸出流
out = new PrintWriter(conn.getOutputStream());
// 傳送請求引數
out.print(param);
// flush輸出流的緩衝
out.flush();
// 定義BufferedReader輸入流來讀取URL的響應
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
}
//使用finally塊來關閉輸出流、輸入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
JsonUtils工具類:
/**
* Json轉物件
* @param json
* @param type
* @param <T>
* @return
*/
public static <T> T convertJson2Object(String json, Class<T> type) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
return mapper.readValue(json, type);
}
登入就可以實現了,如果大家有什麼問題,可以隨時留言。。。