• 微信access_token和refresh_token保存于redis


    简介

    • 通常理解的access_token和refresh_token
      • access_token是用来对客户端进行认证的,类似与密码,有一定的有效期。当过期后可使用refresh_token重新获取一个新的access_token。refresh_token的有效期相对较长
    • 微信开发设置到两种access_token
      • 第一种是接口授权access_token,是用来调用微信高级接口的,有次数限制,是来区分公众号的
      • 另外一种是用户授权access_token,是用户授权公众号获取用户信息是得到的,无次数限制,使用用来区分用户的(一般用在微信H5开发上)
    • 由于上述第一种access_token是有次数限制的,因此我们需要将太缓存(保存)起来,每次调用接口的时候先取我们缓存的access_token,而不是从新获取一个新的access_token。
    • 由于refresh_token的有效期相对较长,且使用频率较少,此处只说明access_token的保存(refresh_token可类似处理)

    使用redis保存access_token

    • 微信公众平台API每日有调用上限,即使某些公众号或服务号有清零某些接口调用的次数权限,但也架不住滥用或错误的调用,官方建议access_token由一台服务来维护和提供查询功能,另外特别重要的一点是每个凭证都拥有生命周期,长短不同,access_token的生命周期是7200秒,在这段时间内可以重复使用,所以不要在每使用一次凭证就重新获取一个access_token了。
    • 通常会保存在内存数据库中,如Redis,当然也可以直接放在应用程序的内存中,不建议放在oracle或MySQL,拿取开销较比其它手段太重。放在内存数据库中的好处较比放在应用程序的内存中是维护性好,尤其是搭配了可视化管理工具后。另外不仅可以放access_token,也可以其它数据库。[^1] [^2]
    • 示例(基于springboot)

      • redis等其他基础配置省略

      • application.yml 其中myapp下的key都需要进行自定义参数配置,此处也存储了用户授权access_token

        myapp:
            redisWxUserAccessToken: "user.wxUserAccessToken"
            redisWxUserRefreshToken: "user.wxUserRefreshToken"
            redisWxAccessToken: "sys.wxAccessToken"
            redisWxRefreshToken: "sys.wxRefreshToken"
        
      • 此处以保存用户授权access_token为例,接口调用access_token可在项目启动时进行缓存。部分代码如下:

        @Autowired
        private RedisTemplate<String, String> redisTemplate;
        
        @Value("${myapp.redisWxUserAccessToken}")
        private String redisWxUserAccessToken;
        
        // 获取
        public String getUserAccessToken(Object userId) {
            String accessToken = null;
            if(StringUtils.isEmpty(userId)) return accessToken;
        
            String accessTokenStr = (String) redisTemplate.opsForHash().get(redisWxUserAccessToken, String.valueOf(userId));
            long now = (new Date()).getTime();
            if(!StringUtils.isEmpty(accessTokenStr)) {
                String[] arr = accessTokenStr.split("#");
        
                if(now < Long.valueOf(arr[1])) {
                    accessToken = arr[0];
                }
            }
        
            if(StringUtils.isEmpty(accessToken)) {
                accessToken = getUserAccessTokenByRefreshToken(userId);
            }
        
            return accessToken;
        }
        
        
        // 重新获取
        Object expiresIn = accessTokenMap.get("expires_in"); // 调用微信授权接口后,返回的expires_in参数
        String value = accessTokenNew + "#" + getNowExpiresIn(expiresIn); // 此处是设置有效期
        redisTemplate.opsForHash().put(redisWxUserAccessToken, String.valueOf(userId), value);
        
        
        public Long getNowExpiresIn(Object expiresIn) {
            long now = (new Date()).getTime();
            if(expiresIn == null) return now;
        
            Long expiresMs = Long.valueOf(String.valueOf(expiresIn)) - 15 * 60;
            return expiresMs * 1000 + now;
        }
        

    [^1] 网页授权的access_token大家是怎么缓存的
    [^2] https://segmentfault.com/q/1010000004995599/a-1020000005016398

  • 相关阅读:
    Myeclipse学习总结(5)——Myeclipse常用快捷键再学习
    Myeclipse学习总结(5)——Myeclipse常用快捷键再学习
    Java基础学习总结(37)——Java23中设计模式(Design Patterns)详解
    Java基础学习总结(37)——Java23中设计模式(Design Patterns)详解
    Java基础学习总结(37)——Java23中设计模式(Design Patterns)详解
    Git学习总结(4)——我的Git忽略文件
    Git学习总结(4)——我的Git忽略文件
    Git学习总结(4)——我的Git忽略文件
    《跟唐老师学习云网络》 -第5篇 Ping喂报文
    深入比特币原理(五)——高级交易与脚本
  • 原文地址:https://www.cnblogs.com/oldinaction/p/7638106.html
Copyright © 2020-2023  润新知