最近在做微信的发送模版消息,在测试的时候发现有的时候能够发送,有时候无法发送,查了相关的日志(日志记录发送结果很重要!!),看到了微信返回的错误消息,发现是 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的场景很多,别弄混了~

关于access_token过期的解决办法的更多相关文章

  1. Hybris license过期的解决办法

    license过期编译是可以通过的,但是启动服务会报错: LICENSE VERIFICATION HAS FAILED! Your demo/develop license has expired, ...

  2. 使用history.back()出现"警告: 网页已过期的解决办法"

    原因: 表单提交页面中使用了 session_start 函数.由于我们后退浏览的是缓存页,而该函数会强制当前页面不被缓存. 解决: PHP: 此提示出现在一个POST提交的页面,点到其它页面后,通过 ...

  3. 谷歌Chrome浏览器提示adobe flash player已过期完美解决办法

    最近使用谷歌Chrome浏览器提示adobe flash player已过期,浏览网页时一些flash元素的东西都无法正常显示,在网上尝试寻找很多方法,都不能解决,最后,经测试有效方法如下:一:下载最 ...

  4. 【Oracle】ora-28001 ora-28002提示用户密码即将过期的解决办法

    -- 1.首先查看用户的配置文件中的用户密码生命周期,一般情况下默认是180天.登录时系统提示ora-28002该用户即将过期 -- 可以先查看一下各用户的状态 SELECT username,PRO ...

  5. [经验交流] kubeadm 安装 kubernetes 一年过期的解决办法

    kubeadm 是 kubernetes 提供的一个初始化集群的工具,使用起来非常方便.但是它创建的apiserver.controller-manager等证书默认只有一年的有效期,同时kubele ...

  6. Oracle提示密码快过期的解决办法

    今天在使用ORACLE时报出如下错误:ORA-28002: the password will expire within 7 days================================ ...

  7. 更换mac电脑后证书过期的解决办法

    http://stackoverflow.com/questions/32821189/xcode-7-error-missing-ios-distribution-signing-identity- ...

  8. Xshell、Xftp评估过期的解决办法

    介绍一个     FTP客户端-IIS7服务器管理工具作为FTP客户端,它支持批量管理ftp站点.定时上传和定时下载,定时备份,且操作简洁.同时iis7服务器管理工具还是vnc客户端.并且支持批量管理 ...

  9. (转)苹果iOS开发者账号过期临时解决方法

    苹果iOS开发者账号过期临时解决办法 苹果iOS开发者账号一年的费用是99美金,作者最近由于各种原因,导致renew没能在账号过期之前支付好,所以在账号过期等待renew的期间,试了试一些非正常手段, ...

随机推荐

  1. ES6,Array.includes()函数的用法

    在ES5,Array已经提供了indexOf用来查找某个元素的位置,如果不存在就返回-1,但是这个函数在判断数组是否包含某个元素时有两个小不足,第一个是它会返回-1和元素的位置来表示是否包含,在定位方 ...

  2. [Python Study Notes]CS架构远程访问获取信息--Client端v1.0

    更新内容: 1.添加entry栏默认ip和port口 2.修正退出功能 3.添加退出自动关闭窗口功能 4.优化cpu显示为固定保留两位小数 '''''''''''''''''''''''''''''' ...

  3. PLECS_晶闸管调速系统_9w

    3. 直流电机开环调压调速系统模型搭建 (1)电路图 (2)仿真 当 α = pi / 2.7 的时候,直流电机的稳定转速大约保持很低的速度. 随着α的减少,直流电机的速度逐渐增大.当α = pi / ...

  4. 【转】Nginx配置详解

    转自:http://www.cnblogs.com/knowledgesea/p/5175711.html Nginx常用功能 1. Http代理,反向代理:作为web服务器最常用的功能之一,尤其是反 ...

  5. visual studio code右侧的预览面板能关闭吗?

    https://segmentfault.com/q/1010000010082399   "editor.minimap.enabled":false

  6. Apache设置二级域名和虚拟主机

    apache  httpd.conf 最后: ------------------------------NameVirtualHost *:80<VirtualHost *:80>    ...

  7. 【NOIP2015】字串

    [NOIP2015]字串 标签: DP NOIP Description 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其 ...

  8. springmvc 对 jsonp 的支持

    在与前端开发人员合作过程中,经常遇到跨域名访问的问题,通常我们是通过jsonp调用方式来解决.jsop百科:http://baike.baidu.com/link?url=JKlwoETqx2uuKe ...

  9. 剑指offer第八天

    32.把数组排成最小的数 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323 ...

  10. hihoCoder1310 岛屿 (dfs)

    思路:首先dfs求得所有联通块,再搜索的同时把每个联通块的坐标都保存下来,然后把每个联通块处理一下–首先得到某个联通块的最小横坐标和纵坐标,然后让每个坐标去减去这个横坐标和纵坐标.相当于使得所有联通块 ...