記錄下微信開發遇到的遇到的幾種授權,待繼續填充
一 開放平臺-網站應用
詳情閱讀 官方文檔
1.1 獲取授權 access_token 以及標識 openid 。
method: get
param: appid = 應用唯一標識,secret = 應用祕鑰,code = 調用 wx.login() 請求獲取.
若請求正確,解析請求結果即可拿到 access_token (需要緩存,緩存時注意緩存時間,否則可能造成緩存數據與微信服務端數據不一致的情況)與 openid (最好緩存).要仔細檢查 appid 與 secret 的是指否正確,還要注意的是 code 只能使用一次,多次使用會返回狀態碼 40029,提示無效的code.
1.2 通過授權 openid 獲取用戶信息,包含 unionid
method: get
url: https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
param: 1步驟獲取的對應值
若請求正確,解析請求結果即可拿到用戶基本信息,包含 unionid .
需要理解的是 openid 是普通用戶的標識,對當前開發者帳號唯一,而 unionid 是用戶統一標識。針對一個微信開放平臺帳號下的應用,同一用戶的unionid是唯一的。但是要想獲取 unionid,必須要求應用綁定微信開放平臺.如果未綁定,會出現獲取不到 unionid 的情況.
二 小程序
詳情閱讀 官方文檔
2.1 獲取標識 openid 以及會話祕鑰 session_key
method: get
param: appid = 小程序appId,secret = 小程序appSecret,code = 調用 wx.login() 請求獲取.
沒有做雲開發,忽略圖中 5.6,若果滿足圖中條件 2,3,4, 若請求正確,解析請求結果不僅能拿到 openid 與 session_key,還能直接拿到 unionid.沒有拿到,繼續按照步驟 2.2 操作
2.2 解密獲取unionid
在強調一次,一定要綁定開放平臺才能夠獲取.
調用 wx.getUserInfo(Object object) ,獲取到 userInfo,rawData, signature, encryptedData, iv, cloudID
通過獲取到的部分信息進行解密,拿到 unionid,也可同時獲取用戶其他信息,具體的解密步驟可參考下面
2.2.1 編寫 AES 對稱解密工具類
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
public class AESutil {
public static boolean initialized = false;
/**
* AES對稱解密工具類
*
* @param content 密文
* @return
* @throws InvalidAlgorithmParameterException
* @throws NoSuchProviderException
*/
public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
initialize();
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
Key sKeySpec = new SecretKeySpec(keyByte, "AES");
// 初始化
cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void initialize() {
if (initialized){
return;
}
Security.addProvider(new BouncyCastleProvider());
initialized = true;
}
// 生成iv
public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IvParameterSpec(iv));
return params;
}
}
2.2.2 解密
import com.alibaba.fastjson.JSONObject;
import com.yilaiyiwang.consultation.utils.AESutil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
/**
* @param iv 加密算法的初始向量
* @param encryptedData 包括敏感數據在內的完整用戶信息的加密數據
* @param openId 用戶此程序的唯一標識,2.1 步驟獲取
* @param rawData 不包括敏感信息的原始數據字符串
* @param signature 使用 sha1( rawData + sessionkey ) 得到字符串,用於校驗用戶信息
*/
public String getUnionId(String iv, String encryptedData, String openId, String rawData, String signature) {
// 獲取2.1中的請求到sessionKey
String sessionKey = " 2.1 步驟獲取的值";
// 本地加密後的數據
String sha = DigestUtils.sha1Hex(rawData + sessionKey);
// 檢查本地加密後的數據是否與接收到的加密數據一致
if (!sha.equals(signature)) {
return "數據不一致";
}
byte[] dataByte = Base64.decodeBase64(encryptedData);
// 加密祕鑰
byte[] keyByte = Base64.decodeBase64(sessionKey);
// 偏移量
byte[] ivByte = Base64.decodeBase64(iv);
String userInfo;
String unionid = null;
try {
byte[] resultByte = AESutil.decrypt(dataByte, keyByte, ivByte);
if (null != resultByte && resultByte.length > 0) {
userInfo = new String(resultByte, "UTF-8");
JSONObject jsonObject = JSONObject.parseObject(userInfo);
unionid = (String) jsonObject.get("unionId");
return unionid;
}
} catch (Exception e) {
e.printStackTrace();
}
return "未獲取到unionid";
}