• 关于access_token过期的解决办法


    最近在做微信的发送模版消息,在测试的时候发现有的时候能够发送,有时候无法发送,查了相关的日志(日志记录发送结果很重要!!),看到了微信返回的错误消息,发现是 invalid credential, access_token is invalid or not latest hint: [QM1DJA0040vr22],原来是assess_token过期了。

    我想了问题可能出现在下面几点:

    1. 测试服和线上服使用同一个app_id和secret来获取,可能会存在其中一方获取的token是旧的;

    2. 代码中没有统一的从一个地方来获取,而是直接从官网获取,导致不统一(看了代码,没有发现单独获取token的地方);

    3. 请求获取新的token的时候失败(应该不可能,因为请求成功以后会在redis中缓存两个小时,但是发现没过多久又再次失效,因此主要原因应该不是这个);

    4. 异步队列等待的时间较长,正好执行的时候token已经更新(应该不可能,获取token是在异步函数中执行,而不是通过函数参数来传递);

    但是实在想不出问题确切的原因,也只能先在其基础上进行fix了。

    我的做法:是在内层函数中,如果执行失败,并且是access_token过期的异常,则会在request的时候抛出专门的异常。在外围函数如果接收到了这个异常,则会抛出让装饰器接收到,装饰器收到这个异常后会删掉缓存中的token,并且重新执行该函数,这样该函数在执行的时候,就会去主动的获取最新的token。我大致写了下代码,如下:

    # -*- coding: utf-8 -*-

    from functools import wraps
    from django.utils.decorators import available_attrs
    import logging


    class WeiXinTokenExpiredException(Exception):
       pass


    def _delete_weixin_expired_access_token():
       """
      删除微信过期的token
      """
       pass


    def _send_weixin_mini_template_msg(msg):
       """
      发送微信模版信息
      :param msg:
      :return:
      """
       return {}


    def weixin_token_expired_decorator(func):
       """
      捕获微信asess_token过期的装饰器
      如果抛出WeiXinTokenExpiredException,则删除缓存中的token
      并且重新执行
      :param func: 执行函数
      """
       def decorator(view_func):
           @wraps(view_func, assigned=available_attrs(view_func))
           def _wrapped_view(*args, **kwargs):
               try:
                   return view_func(*args, **kwargs)
               except WeiXinTokenExpiredException:
                   _delete_weixin_expired_access_token()
                   return view_func(*args, **kwargs)

           return _wrapped_view

       if func is None:
           return decorator

       return decorator(func)


    @weixin_token_expired_decorator
    def push_weixin_mini_template_msg(msg):
       """
      发送模版消息
      :param msg:
      :return:
      """
       result = {}
       try:
           result = _send_weixin_mini_template_msg(msg)
           logging.info("_send_weixin_mini_result %s", result)
       except:
           if 'error_code' in result and result['error_code'] == 42001:
               raise WeiXinTokenExpiredException
       return result

    吐槽一下,微信获取token的场景很多,别弄混了~

  • 相关阅读:
    Delphi stdCall意义
    Delphi 与 DirectX 之 DelphiX(10): TPictureCollectionItem.StretchDraw
    delphi中的TCollection
    Delphi XE5教程8:使用Delphi命名空间
    在 centos 系统中添加审计用户并利用 sudoers 进行权限控制
    在 centos 8 中添加 sudoer 用户
    React.Fragment
    js保留两位小数方法总结
    正则表达式的() [] {} 的区别
    Typora如何配置gitee图床
  • 原文地址:https://www.cnblogs.com/George1994/p/8544559.html
Copyright © 2020-2023  润新知