微信公众号或小程序中心服务器存储微信access_token

小程序获取access_token官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html
公众号获取access_token官方文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html

关于access_token的重要性,不言而喻,当需要调用公众号或小程序的众多接口时,都需要用到

此片文章主要将使用中控服务器统一获取和刷新access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务;

使用的是redis作为中心服务器来存储access_token,过期自动刷新

上代码:

import logging
import requests
import time
from pickle import dumps, loads

from requests.compat import json as _json

from django.conf import settings

from werobot.client import Client

from utils.redis_db import redis # 自己封装的redis
from utils import util

logger = logging.getLogger('sdk')



# shixf  自己写一个简单的redis哈希存储access_token,并检测更新
# 验证返回值函数
class ClientException(Exception):
    pass
def check_error(json):
    """
    检测微信公众平台返回值中是否包含错误的返回码。
    如果返回码提示有错误,抛出一个 :class:`ClientException` 异常。否则返回 True 。
    """
    if "errcode" in json and json["errcode"] != 0:
        raise ClientException("{}: {}".format(json["errcode"], json["errmsg"]))
    return json


class Wechatopen(object):
    '''
    存储access_token
    '''
    # 定义redis的key
    key = 'access_token_hash'
    def __init__(self):
        self._token = None
        self.token_expires_at = None
        self.appid = settings.WECHAT_APP_ID # 使用自己的公众号或小程序的APP_ID
        self.appsecret = settings.WECHAT_APP_SECRET # 使用自己公众号或小程序的SECRET

    def request(self, method, url, **kwargs):
        if "params" not in kwargs:
            kwargs["params"] = {"access_token": self.token}
        if isinstance(kwargs.get("data", ""), dict):
            body = _json.dumps(kwargs["data"], ensure_ascii=False)
            body = body.encode('utf8')
            kwargs["data"] = body

        r = requests.request(
            method=method,
            url=url,
            **kwargs
        )
        r.raise_for_status()
        json = r.json()
        if check_error(json):
            return json

    def get(self, url, **kwargs):
        return self.request(
            method="get",
            url=url,
            **kwargs
        )

    def get_access_token(self):
        """
        判断现有的token是否过期。
        用户需要多进程或者多机部署可以手动重写这个函数
        来自定义token的存储,刷新策略。

        :return: 返回token
        """
        # 从redis中取出access_token和过期的额时间,并赋值给self._token和self.token_expires_at
        stream = redis.get(self.key)
        if stream:
            self._token,self.token_expires_at = loads(stream)
        if self._token:
            now = time.time()
            if self.token_expires_at - now > 60:
                logger.info('access_token没有过期')
                logger.info('access_token的值为{}'.format(self._token))
                return self._token
        # 如果过期的话,重新生成access_token,重置_token和token_expires_at
        json = self.grant_token()
        self._token = json["access_token"]
        self.token_expires_at = int(time.time()) + json["expires_in"]
        # 存入redis
        access_token_val = dumps([self._token,self.token_expires_at])
        redis.set(self.key,access_token_val)
        logger.info('access_token已经过期')
        logger.info('新生成的access_token值为{}'.format(self._token))
        return self._token

    def grant_token(self):
        """
        获取 Access Token。
        每当调用这个包,便将数据存入reids,并且更新self._token和self.token_expires_at

        :return: 返回的 JSON 数据包
        """
        result = self.get(
            url="https://api.weixin.qq.com/cgi-bin/token",
            params={
                "grant_type": "client_credential",
                "appid": self.appid,
                "secret": self.appsecret
            }
        )
        return result


class PreWechatOpenAPIClient(Client):
    """
    微信第三方平台调用对应授权过来的API
    """
    def __init__(self, app_id):
        self.app_id = app_id


# shixf  重写
    def get_access_token(self):
        """
        判断现有的token是否过期。
        用户需要多进程或者多机部署可以手动重写这个函数
        来自定义token的存储,刷新策略。

        :return: 返回token
        """
        wechatopen = Wechatopen()
        return wechatopen.get_access_token()


    # 重写self.token
    @property
    def token(self):
        return self.get_access_token()

# 当需要使用access_token,只需要调用PreWechatOpenAPIClient类的get_access_token方法,就可以获取到永远正确的access_token
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值