微信开发---授权登录

记录下微信开发遇到的遇到的几种授权,待继续填充

一 开放平台-网站应用

    详情阅读 官方文档

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

 

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