zno2

小程序入门

入口 https://mp.weixin.qq.com/cgi-bin/wx

api   https://developers.weixin.qq.com/miniprogram/dev/index.html

ebook  https://developers.weixin.qq.com/ebook?action=get_post_info&docid=000cc48f96c5989b0086ddc7e56c0a&highline=jscode2session

 

一、登录

1. 流程

小程序 -> api -> wx.login 

2. 获取 session_key 等 

https://api.weixin.qq.com/sns/jscode2session?appid=<AppId>&secret=<AppSecret>&js_code=<code>&grant_type=authorization_code

参数: appid 注册获取,secret 注册获取 (小程序是采用对称加密), js_code 小程序获取上传给服务器

返回值:

openid 微信用户的唯一标识
session_key 会话密钥
unionid 用户在微信开放平台的唯一标识符。本字段在满足一定条件的情况下才返回。

3. 小程序获取用户信息,后端服务验证签名

wx.getUserInfo 获取数据提交给服务器 

https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserInfo.html

userInfo OBJECT 用户信息对象,不包含 openid 等敏感信息
rawData String 不包括敏感信息的原始数据字符串,用于计算签名。
signature String 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息,参考文档 signature。
encryptedData String 包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法
iv String 加密算法的初始向量,详细见加密数据解密算法

服务器根据验签规则验证签名,通过后登录成功,生成自己sessionid  

注:验签获取明文数据,对称解密获取敏感数据 (对称解密时可以下载示例,java单元测测试是否正确)

package cn.zno.newstar.base.utils.secu;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。
 * 
 * @author zxg
 * @see https://en.wikipedia.org/wiki/Cipher_suite
 * @see https://tools.ietf.org/html/rfc2315
 * @see https://tools.ietf.org/html/rfc2898
 */
public class AEC128CBCUtils {

    /**
     * 操作对象是原始流
     * @param target
     * @param secretKey
     * @param iv
     * @param mode
     * @return
     */
    private static byte[] toggle(byte[] target, byte[] secretKey, byte[] iv, int mode) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec key = new SecretKeySpec(secretKey, "AES");
            IvParameterSpec algorithm = new IvParameterSpec(iv);
            cipher.init(mode, key, algorithm);
            return cipher.doFinal(target);
        } catch (Exception e) {
            throw new RuntimeException("对称算法异常", e);
        }
    }
    
    /**
     * 操作对象是 Base64 utf-8 编码的字符串 (返回的也是)
     * @param target
     * @param secretKey
     * @param iv
     * @return
     */
    public static String encrypt(String target, String secretKey, String iv) {
        
        try {
            // 获取流
            byte[] targetByteArray = Base64Utils.decodeFromString(target);
            byte[] secretKeyByteArray = Base64Utils.decodeFromString(secretKey);
            byte[] ivByteArray = Base64Utils.decodeFromString(iv);

            // 加密
            byte[] toggle = toggle(targetByteArray, secretKeyByteArray, ivByteArray, Cipher.ENCRYPT_MODE);

            // 转 utf-8 base64
            return Base64Utils.encodeToString(toggle);
        } catch (Exception e) {
            throw new RuntimeException("加密失败", e);
        }
    }

    /**
     * 操作对象是 Base64 utf-8 编码的字符串 (返回是原始数据)
     * @param target
     * @param secretKey
     * @param iv
     * @return
     */
    public static String decrypt(String target, String secretKey, String iv) {

        try {
            // 获取流
            byte[] targetByteArray = Base64Utils.decodeFromString(target);
            byte[] secretKeyByteArray = Base64Utils.decodeFromString(secretKey);
            byte[] ivByteArray = Base64Utils.decodeFromString(iv);

            // 解密
            byte[] toggle = toggle(targetByteArray, secretKeyByteArray, ivByteArray, Cipher.DECRYPT_MODE);

            // 转明文
            return new String(toggle, "utf-8");
        } catch (Exception e) {
            throw new RuntimeException("解密失败", e);
        }
    }

}
View Code

 session 失效策略:

1) 开发者服务器自有session 失效,则重新登录 (即便wx session_key 未失效,也不再调用wx服务器)

2)wx服务器session_key 失效,则重新登录(可通过wx.checkSession() 延期,尽量避免其失效,如果失效,开发者服务器应强行退出登录状态,令客户端重新登录)

posted on 2023-06-09 13:34  zno2  阅读(16)  评论(0编辑  收藏  举报

导航