微信小程序登录及登录态管理

一,小程序登录

小程序登录 | 微信开放文档

接口应在服务器端调用,详细说明参见服务端API

接口说明

接口英文名

code2Session

功能描述

登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。更多使用方法详见小程序登录。

调用方式

HTTPS 调用


GET https://api.weixin.qq.com/sns/jscode2session 

请求参数

属性类型必填说明
appidstring小程序 appId
secretstring小程序 appSecret
js_codestring登录时获取的 code,可通过wx.login获取
grant_typestring授权类型,此处只需填写 authorization_code

返回参数

属性类型说明
session_keystring会话密钥
unionidstring用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台账号下会返回,详见 UnionID 机制说明
errmsgstring错误信息
openidstring用户唯一标识
errcodeint32错误码

调用示例

示例说明: HTTPS请求

请求数据示例


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

返回数据示例


{
"openid":"xxxxxx",
"session_key":"xxxxx",
"unionid":"xxxxx",
"errcode":0,
"errmsg":"xxxxx"
}
 

错误码

错误码错误码取值解决方案
40029code 无效js_code无效
45011api minute-quota reach limit  mustslower  retry next minuteAPI 调用太频繁,请稍候再试
40226code blocked高风险等级用户,小程序登录拦截 。风险等级详见用户安全解方案
-1system error系统繁忙,此时请开发者稍候再试

二,小程序登录流程图

小程序登录 | 微信开放文档

小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。

登录流程时序

说明:
  1. 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
  2. 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 、 用户在微信开放平台账号下的唯一标识UnionID(若当前小程序已绑定到微信开放平台账号) 和 会话密钥 session_key

之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

注意:

  1. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥
  2. 临时登录凭证 code 只能使用一次

三,接口调用频率规范

接口调用频率规范 | 微信开放文档

概念介绍

小程序wx接口可分为“普通接口”和“限频接口”。

“限频接口”指的是一个用户在一段时间内不允许频繁调用的wx接口,此类接口一般会调用到微信后台系统资源,为了保护系统,同时防止用户资源被滥用,开发者需要对此类接口做适度的频率限制,不能无节制地调用。

平台会对小程序内“限频接口”的调用情况做监控,如果小程序对此类接口的调用频率超出平台的规范,将会收到站内信提醒。系统会在资源紧张的情况下优先保障合理使用的小程序的服务。

开发者可登录小程序管理后台-开发管理-接口设置中查看“限频接口”调用情况。

目前,“限频接口”包括以下接口:

  1. wx.login
  2. wx.checkSession
  3. wx.getSetting
  4. wx.getUserInfo
  5. wx.getUserProfile

优化方法

开发者可以参考以下方法对“限频接口”的调用频率做优化:

  • 把上一次调用接口的返回结果缓存下来以供后续逻辑复用,而不是重新调用接口
  • 避免在定时循环的逻辑内重复调用“限频接口”
  • 避免在页面初始化事件onLoadonShowonReady中调用限频接口,应该在小程序初始化事件onLaunch中调用

四,登录流程及服务端缓存方案

登录流程

  1. 打开小程序,前端调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
  2. 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 、 用户在微信开放平台账号下的唯一标识UnionID(若当前小程序已绑定到微信开放平台账号) 和 会话密钥 session_key

实际项目中登录及服务端缓存方案

1. 打开小程序,前端调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。

2.调用登录服务端接口,参数如下(登录请求入参),后台做如下判断

1>判断code是否为空,

不为空

调用微信接口code2Session,获取openID及会话密钥session_key,并缓存,key=前缀+session_key,value = openID,过期时间10min

为空

根据请求中,sessionKey直接从缓存中获取openID

空,抛出异常非法登录

非空,继续后续流程

想一下什么时候code为空,什么时候不为空

打开小程序,如下二图,调用登录服务端登录接口,入参只有一个code

再次点击‘允许’时,再次调用登录服务端登录接口,入参没有code,有其他参数如下

{
    "mobileEncryptedData":"pRQAS9OpYTlfJIWnznDpHV6QWUmBQNDnrx9pym1cBkoknXz+B3sCrdAyF8crXR2QeqO3A0x3OUUyKYqtfVPC7dtluvIKxdoWDMkEnlMgaaO7E16YDR9KPA85oWtCmTVDsvmxdBvq7uuc+TVx5CfU+JIqDlDFO6M4YRf++uvET0pkHvgA3fXuHA//sMgGNzzbm/rEFAq0u1A1c9zlOdhS2A==",
    "iv":"czh4XUrTs0egv0CVsbSFBg==",
    "openId":"oDCsO5MY_eiI0hgDABslcGQ03JeE",
    "sessionKey":"XmOmQ77cR01vByTcchk9tQ==",
    "tlLoginLog":{
        "deviceBrand":"devtools",
        "deviceModel":"iPhone 5",
        "systemVersion":"iOS 10.0.1",
        "systemPlatform":"devtools",
        "basicLibraryVersion":"3.0.0",
        "systemLanguage":"zh_CN",
        "appVersion":"8.0.5",
        "wifi":1,
        "bluetooth":1,
        "geographical":1,
        "logonChannel":"miniprogram-wechat",
        "applicationType":"",
        "appCode":"jghc",
        "appEditions":"1.7.11"
    }
}

登录请求入参

public class MobileDTO {

    @ApiModelProperty(name = "mobileEncryptedData", value = "加密字符串")
    private String mobileEncryptedData;

    @ApiModelProperty(name = "iv", value = "偏移量")
    private String iv;

    @ApiModelProperty(name = "pic", value = "pic")
    private String pic;

    @ApiModelProperty(name = "code", value = "code")
    private String code;

    @ApiModelProperty(name = "sessionKey", value = "sessionKey")
    private String sessionKey;

    @ApiModelProperty(name = "appCode", value = "每个平台的code")
    private String appCode;

    @ApiModelProperty(name = "tlLoginLog", value = "新增设备信息")
    private TlLoginLog tlLoginLog;

    @ApiModelProperty(name = "toc", value = "1,2")
    private String toc;
}

五,关于手机号加解密

参考

对称加密算法 - 廖雪峰的官方网站

1,前端加密

AES对称加密,密钥sessionKey,偏移量iv

注意加密后的手机号密文,sessionkey,iv都进行了base64编码

2,后端解密

根据入参密钥sessionKey,偏移量iv,解密

代码如下

public static JSONObject 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");
                return JSONObject.parseObject(result);
            }
        } catch (Exception e) {
            log.error("微信用户信息解密失败!", e);
        }
        return null;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值