Python实现Token过期自动刷新并重试原请求

文章目录

  • 问题描述
  • 解决方案
  • 代码
  • 参考文献

问题描述

本人系统经常与上游系统进行交互,其中获取 Token 的接口调用次数过多,想将它存储在内存中,在请求失败后再重新获取 Token 继续进行原请求。




解决方案

灵感来自 sbzhu 的项目 weworkapi_python,十分巧妙

def httpCall(self, urlType, args=None) : shortUrl = urlType[0]method = urlType[1]response = {}for retryCnt in range(0, 3) :  # 重试三次,可用于重新获取 Token 后继续进行原请求# 正常进行原请求if 'POST' == method :url = self.__makeUrl(shortUrl)response = self.__httpPost(url, args)elif 'GET' == method :url = self.__makeUrl(shortUrl)url = self.__appendArgs(url, args)response = self.__httpGet(url)else : raise ApiException(-1, "unknown method type")# check if token expiredif self.__tokenExpired(response.get('errcode')) :  # 校验 Token 是否过期self.__refreshToken(shortUrl)  # 过期则刷新retryCnt += 1continueelse :  # 不过期则跳出重试机制breakreturn self.__checkResponse(response) 




代码

上游服务器

import os
import datetime
import tracebackimport jwt
from flask import Flask, request, current_app, jsonify, abortapp = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY') or 'this is a secret'
pass_paths = ['/get_token']  # 跳过验证的访问路径@app.before_request
def before_request():"""Token验证"""need_verify = True  # 是否需要验证for path in pass_paths:if request.path.endswith(path):need_verify = Falsebreakif need_verify:try:Token = request.headers.get('Token')key = current_app.config['SECRET_KEY']jwt.decode(Token, key, algorithms=['HS256'])except:traceback.print_exc()abort(401)@app.route('/get_token', methods=['POST'])
def get_token():"""获取Token"""username = request.form.get('username')password = request.form.get('password')if username == 'admin' and password == '123456':  # 身份校验# exp = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(minutes=1)  # 一分钟后exp = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(seconds=3)  # 3秒后payload = {'username': username, 'exp': exp}key = current_app.config['SECRET_KEY']Token = jwt.encode(payload, key, algorithm='HS256')return jsonify({'Token': Token})else:abort(401)@app.route('/get_datetime')
def get_datetime():return jsonify({'time': datetime.datetime.now()})if __name__ == '__main__':app.run()

用户名密码简略为 admin 和 123456

下游服务器

import timeimport requestssession = requests.Session()def raise_exception(response, *args, **kwargs):if response.status_code == 401:print('Retry')headers = get_headers()response.request.headers.update(headers)return session.send(response.request, verify=False)hooks = {'response': raise_exception}def get_headers():get_token_api = 'http://127.0.0.1:5000/get_token'data = {'username': 'admin', 'password': '123456'}response = requests.post(get_token_api, data=data)Token = response.json()['Token']headers = {'Token': Token}return headersget_datetime_api = 'http://127.0.0.1:5000/get_datetime'
headers = get_headers()
time.sleep(4)  # 模拟Token过期
response = requests.get(get_datetime_api, headers=headers, hooks=hooks)
print(response.json())




参考文献

  1. weworkapi_python GitHub
  2. Python requests 高级用法:timeouts、retries、hooks
  3. Python Requests - retry request after re-authentication
  4. RESTful Authentication with Flask

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/82153.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Android][音频] 关于AudioTrack libaudioclient libaaudio

AudioTrack: AudioTrack是Android的PCM播放音频组件,只能用来播放PCM数据,因此AudioTrack往往配合软解组件或者MediaCodec硬解一起工作。大部分情况下,音频的解码都是软解来负责,或者直接交由音频播放设备进行设备端的…

22.2 JavaScript 常用操作

1. BOM操作 浏览器对象模型(BOM): 是JavaScript与浏览器交互的接口集合. 它提供了一组对象, 用于操作浏览器窗口, 历史记录, 文档等. BOM可以通过Javascript代码来访问和控制浏览器的功能和行为.BOM的核心对象是window对象, 它表示浏览器的窗口或框架. 通过window对象, 可以访…

Matlab图像处理-强度分层法

强度分层法 强度分层技术是最简单的伪彩色图像处理方法之一。 如果将一幅图像被描述为空间坐标(x,y) 的强度函数f(x,y) ,则分层的方法可以看作是将一些平面平行于图像坐标平面(x,y) ,然后将每个平面在相交区域切割图像函数。下图展示了使用平面将图像函…

【基础篇】六、基于SpringBoot来整合SSM的案例(下)

文章目录 1、前后端调用:axios发送异步请求2、添加功能3、删除功能4、修改功能5、异常消息处理6、分页功能7、分页Bug处理8、条件查询 接下来加入前端页面,使用axios发送异步请求调用上篇的接口。调前端代码时,发现还挺有趣,刷新、…

基于SSM的电动车租赁网站设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

最新AI创作系统+ChatGPT商业运营源码+支持GPT4.0+支持国内AI模型/支持AI绘画

一、AI创作系统 SparkAi系统是基于很火的GPT提问进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT系统?小编这里写一个详细图文教程吧&#x…

ADB底层原理

介绍 adb的全称为Android Debug Bridge,就是起到调试桥的作用。通过adb我们可以在Eclipse/Android Studio中方便通过DDMS来调试Android程序,说白了就是debug工具。adb是android sdk里的一个工具, 用这个工具可以直接操作管理android模拟器或者真实的and…

Kotlin simple convert ArrayList CopyOnWriteArrayList MutableList

Kotlin simple convert ArrayList CopyOnWriteArrayList MutableList Kotlin读写分离CopyOnWriteArrayList_zhangphil的博客-CSDN博客Java并发多线程环境中,造成死锁的最简单的场景是:多线程中的一个线程T_A持有锁L1并且申请试图获得锁L2,而多…

【数据库系统概论】数据模型

数据模型是什么两类数据模型两步抽象概念模型数据模型 常用的数据模型感谢 💖 数据模型是什么 模型是对现实世界中某个对象特征的模拟和抽象。比如飞机模型就体现了飞机的特性,它模拟飞机的起飞、飞行和降落,它抽象了飞机的基本特征——机头…

C++笔记之文档术语——将可调用对象作为函数参数

C笔记之文档术语——将可调用对象作为函数参数 相关博文:C笔记之函数对象functors与可调用对象 文章目录 C笔记之文档术语——将可调用对象作为函数参数1.在函数参数中传递可调用对象2.‘在参数中传入可调用对象’和‘将可调用对象作为函数参数’哪个描述更加专业…

数据库----数据查询

1.6 查询语句 语法:select [选项] 列名 [from 表名] [where 条件] [group by 分组] [order by 排序][having 条件] [limit 限制]1.6.1 字段表达式 mysql> select 锄禾日当午; ------------ | 锄禾日当午 | ------------ | 锄禾日当午 | ---…

SQL死锁进程内容查询语句

1.方式1 SELECT object_name(A.resource_associated_entity_id) as TABLENAME, A.request_session_id AS SPID,DB_NAME(B.dbid) AS DBName,B.blocked,B.dbid,B.program_name,B.waitresource,B.lastwaittype,B.loginame,B.hostname,B.login_time,B.last_batch--,B.* FROM sy…

redis 集群(cluster)

1. 前言 我们知道,在Web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999% 等等)。但是在Redis语境中,高可用的含义似乎要宽泛一些&#xf…

【面试经典150 | 双指针】判断子序列

文章目录 写在前面Tag题目来源题目解题解题思路方法一:双指针方法二:动态规划 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对…

请求响应状态码

请求与响应&状态码 Requests部分 请求行、消息报头、请求正文。 Header解释示例Accept指定客户端能够接收的内容类型Accept: text/plain, text/htmlAccept-Chars et浏览器可以接受的字符编码集。Accept-Charset: iso-8859-5Accept-Encodi ng指定浏览器可以支持的web服务…

ChatGPT:字符串操作问题——提取包含括号的字符串中的题干内容

ChatGPT:字符串操作问题——提取包含括号的字符串中的题干内容 String title p.text().split(“(”)[0];为什么会报错 ChatGPT: 在这段代码中,您正在使用Java处理一个字符串(假设是HTML或文本),尝试将其分…

三、Mediasoup进程通信实现的原理

Mediasoup 创建父子进程,js与c进程交互的通道 worker.js构造函数中创建父子进程,c通过libuv的socket可以实现 JavaScript 与 C 之间的相互收发消息 一、 父子进程通信 这是一个简单的示例,演示了如何使用 libuv 在父子进程之间进行通信。以…

语义噪声的解释

《Robust Semantic Communications Against Semantic Noise》 定义 语义噪声是一种导致误解语义信息和解码错误的噪声。它导致传输的语义符号和接收到的语义符号之间存在差异,在语义编码、数据传输和语义解码阶段都可能被引入[1] 分类 不同源(文本和图像…

Eclipse开源代码下载

当前插件开发,需要修改eclipse源码,如需要修改remote相关的代码,所以需要下载相关源码。网上大多资料都说的不清不楚的,也可能我太小白,不明白,反正就是折腾了一两天才感觉有点思路,改如何找源码…

virtualbox共享文件夹设置

宿主机是mac os,虚拟机是centos7.9。 一、virtualbox设置共享文件夹 选中虚拟机->设置->共享文件夹->点击号图标进行添加: 二、给虚拟机安装增强功能 打开virtualbox的虚拟机窗口界面,点击窗口顶部菜单中的设备->安装增强功能…