最近在做微信的发送模版消息,在测试的时候发现有的时候能够发送,有时候无法发送,查了相关的日志(日志记录发送结果很重要!!),看到了微信返回的错误消息,发现是 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. C# 使用 Lotus notes 公共邮箱发送邮件

    公司的邮件系统用的是反人类的 Lotus notes, 你敢信? 最近要实现一个功能,邮件提醒功能,就是通过自动发送提醒邮件 前前后后这个问题搞了2天,由于公司的诸多条件限制,无法直接调用到公司发送邮 ...

  2. SDN第四次作业

    作业链接 1.阅读 了解SDN控制器的发展 http://www.sdnlab.com/13306.html http://www.docin.com/p-1536626509.html 了解ryu控 ...

  3. Ansible进阶--playbook的使用

    一.什么是playbooksplaybooks是ansible的脚本.如同shell脚本一样,它是控制远程主机的一系列命令的集合,通过YAML语言编写.执行一些简单的任务,我们可以使用ad-hoc命令 ...

  4. Docker安装Jenkins

    1.下载镜像 docker pull jenkins 2.生成一个容器 docker run -d --name myjenkins -p 8081:8080 -p 50000:50000  --vo ...

  5. go get报错unrecognized import path “golang.org/x/net/context”…

    今天安装gin框架,首先下载gin,命令如下:go get github.com/mattn/go-sqlite3 结果报错: package golang.org/x/net/context: un ...

  6. 利用ajax获取网页表单数据,并存储到数据库之一(使用JDBC)

    所谓JDBC就是利用java与数据库相连接的技术,从数据库获取既有的信息或者把网页上的信息存储到数据库. 这里简单的介绍公司的一个小项目中的一部分,由于代码较多,所以用图片形式进行展示.源码请查看源码 ...

  7. Mybatis 动态使用update语句

    update pf_product_audio_t <trim prefix="set" suffixOverrides=","> <if t ...

  8. struts 中的创建Action的三种方法

    1.对于直接创建类,不实现接口和继承任何的类 例如创建一个helloAction package cn.lonecloud.control; import com.opensymphony.xwork ...

  9. WAMP环境搭建过程中遇到的种种问题

    1,可以选择已经打包好的继承安装包,通常包含apache,mysql,PHP,phpMyadmin.如appserv和wamp. 2,自己分别安装. 第一步:安装mysql,注意设置root对应的密码 ...

  10. SQL注入漏洞产生的原因是什么?怎么防止?XSS呢?

    SQL注入产生的原因:程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行. 防止SQL注入: 1.开启配置文件中的magi ...