小程序开发实现access_token统一管理

2022-04-15 0 664
目录
  • TOKEN 定时刷新器
  • 二、access_token的内部设计
    • 2.1 access_token的时效性
    • 2.2 access_token 的逐渐失效性
  • 三、access_token的统一管理
    • 参考文档

      TOKEN 定时刷新器

      一、背景

      对于使用过公众平台的API功能的开发者来说,access_token绝对不会陌生,它就像一个打开家门的钥匙,只要拿着它,就能使用公众平台绝大部分的API功能。因此,对于开发者而言,access_token的使用方式就变得尤其的重要。在日常API接口的运营中,经常遇到各种的疑问:为什么我的access_token突然非法了?为什么刚刚拿到的access_token,用了10min就过期了?对于这些疑问,我们提供出access_token的设计方案,便于开发者对access_token使用方式上的理解。

      对于access_token的获取,可以参考公众平台的官方文档:auth.getAccessToken、获取Access token

      二、access_token的内部设计

      2.1 access_token的时效性

      众所周知,access_token是通过appid和appsecret来生成的。内部设计的步骤如下:

      (1)开发者通过https请求方式: GET https://API.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET,传入appid及apppsecret的参数

      (2)公众平台后台会校验appid和哈希(appsecret)是否与存储匹配,若匹配,结合当前时间戳,生成新的access_token。

      (3)生成新的access_token的同时,会对老的access_token的过期时间戳更新为当前时间戳。

      (4)返回新的access_token给开发者。

      这里以图示的方式说明一下,新旧token交替过程:

      小程序开发实现access_token统一管理

      从上图需要注意的几点:

      (1)公众平台存储层只会存储新老两个access_token,意味着假设开发者重复调用3次接口,则会导致最早的access_token立刻失效。

      (2)虽然请求新的access_token后,老的access_token过期时间会更新为当前时间,但也不会立刻失效,原理请参考 【2.2 access_token 的逐渐失效性】

      (3)出于信息安全考虑,公众平台并不会明文存储appsecret,仅存储appid以及appsecret的哈希值。因此开发者要妥善保管appsecret。当appsecret疑似泄露时,需要及时登录mp.weixin.qq.com重置appsecret。

      2.2 access_token 的逐渐失效性

      从【access_token的时效性】了解到,当开发者请求获取新的access_token时,老的access_token过期时间会被更新为当前时间,但此时不会立刻失效,因为公众平台会提供【5分钟的新老access_token交替缓冲时间】,因此也称为access_token

      的逐渐失效性。

      实现的原理是:

      • 由于老的access_token过期时间戳已被刷新,所以在API接口请求期间,带上的access_token解开后,过期时间戳会加上5分钟,然后和当前设备时间进行比对,若超过当前设备时间,判断为失效。
      • 公众平台的设备会保持时钟同步,但设备之间仍然可能会存在1-2分钟的时间差异,所以【5分钟】并非绝对的时间值。当开发者获取到新的access_token后应该尽快切换到新的access_token。

      小程序开发实现access_token统一管理

      从上图需要注意的几点:

      (1)由于存在设备时间同步的差异,可能会导致开发者遇到拿着老的access_token请求API接口,部分请求成功,部分请求失败的情况,建议开发者获取到新的access_token后尽快使用。

      (2)通过理解两个图示,对开发者来说,access_token是相当关键且不能乱调的接口,建议开发者统一管理access_token,以免造成多次请求导致access_token失效。

      三、access_token的统一管理

      access_token的更新交给定时触发器完成所有用到access_token的接口调用,不传入access_token,交由后端从数据库中读取

      下面以小程序云函数端统一管理access_token代码为例展示

      index.js 请求并更新access_token

      如果在其他端,需要传入APPID

      const cloud = require('wx-server-sdk')
      cloud.init({
        env: cloud.DYNAMIC_CURRENT_ENV
      })
      const timeutil = require('./timeutil');
      // 需要修改的配置项
      const APPSECRET =  ''
      const axios = require('axios');
      const db = cloud.database();
      // 定时刷新获取配置信息
      const CONFIG = 'cloud-token';
      // 获取TOKEN
      const URL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}'
      function getAccessToken(APPID,APPSECRET){
        let url = URL;
        url = url.replace('{APPID}',APPID)
        url = url.replace('{APPSECRET}',APPSECRET)
        return new Promise(function(resolve,reject){
          axios.get(url).then(function (response) {
            console.log(response);
            resolve(response)
          })
          .catch(function (error) {
            console.log(error);
            reject(error)
          });
        })
      }
      // 云函数入口函数
      exports.main = async (event, context) => {
        const wxContext = cloud.getWXContext()
        // 自动获取当前应用APPID
        var APPID = wxContext.APPID;
        return new Promise(function(resolve,reject){
          getAccessToken(APPID,APPSECRET).then(async res=>{
            console.log(res)
            let access_token = res.data.access_token;
            let ans =  await db.collection(CONFIG).doc('access_token').set({
              data:{
                value:access_token,
                _updateTime:timeutil.TimeCode()
              }
            })
            resolve(ans)
          })
        }) 
      }

      config.json 定时触发器

      每小时触发一次

      {
        "triggers": [
          {
            "name": "myTrigger",
            "type": "timer",
            "config": "0 0 * * * * *"
          }
        ]
      }
      

      timeutil.js 时间工具类

      function TimeCode() {
        var date = new Date();
        var year = date.getFullYear()
        var month = date.getMonth() + 1
        var day = date.getDate()
      
        var hour = date.getHours()
        var minute = date.getMinutes()
        var second = date.getSeconds()
      
        return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
      }
      //获取日期
      function _formatTime(time) {
        var date = time.getFullYear() + '年' + time.getMonth() + '月' + time.getDate() + '日'
        var ftime = time.getHours() + '时' + time.getMinutes() + '分' + time.getSeconds() + '秒'
        return date + ftime;
      }
      function TimeCodeYmd(){
        var date = new Date();
        var year = date.getFullYear()
        var month = date.getMonth() + 1
        var day = date.getDate()
      
        return [year, month, day].map(formatNumber).join('-');
      }
      function formatNumber(n) {
        n = n.toString()
        return n[1] ? n : '0' + n
      }
      module.exports={
        TimeCode,
        TimeCodeYmd
      }
      

      其他云函数中使用到access_token的地方,通过查询数据库进行获取,二者通过数据库进行逻辑耦合。

      access_token 查询使用

      const TOKEN = 'cloud-token';
      //获取access_token 
        try {
          let tres = await db.collection(TOKEN).doc('access_token').get();
          access_token = tres.data.value;
          console.log(access_token)
        } catch (error) {
          console.log('--无token记录--')
          return {
            errCode:-1,
            errMsg:'数据库中无TOKEN信息'
          }
        }
      

      参考文档

      【1】公众平台/小程序服务端API的access_token的内部设计 | 微信开放社区 (qq.com)

      【2】auth.getAccessToken | 微信开放文档 (qq.com)

      【3】微信小程序开发技巧总结(三)– 云开发时效数据刷新和存储 (access_token等) – Kindear – 博客园 (cnblogs.com)

      到此这篇关于小程序开发实现access_token统一管理的文章就介绍到这了,更多相关小程序 access_token统一管理内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码!

      免责声明:
      1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

      2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
      如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
      如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

      NICE源码网 JavaScript 小程序开发实现access_token统一管理 https://www.niceym.com/29880.html