微信開發---授權登錄

記錄下微信開發遇到的遇到的幾種授權,待繼續填充

一 開放平臺-網站應用

    詳情閱讀 官方文檔

    1.1 獲取授權 access_token 以及標識 openid 。

    method: get

    url: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

    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

    url: https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

    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";
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章