如何在Flask中优雅的使用装饰器刷新令牌

随着现代应用对安全性和用户体验的不断追求,令牌验证和刷新机制已成为每个开发者必须掌握的技能。在这篇引人入胜的技术文章中,我们将深入探讨如何使用Python装饰器优雅地处理访问令牌的刷新,让您的代码不仅高效而且易于维护。

一、引言

在当今的Web应用中,OAuth 2.0和JWT(JSON Web Tokens)已经成为身份验证和授权的主流技术。然而,这些技术的核心挑战之一是如何在访问令牌过期后无缝地刷新它,同时不中断用户的体验。本文将向您展示如何利用Python的强大装饰器功能,轻松实现这一目标。

二、装饰器基础

装饰器是Python中一种高级的语言特性,它允许我们在不修改原始函数代码的情况下,增加额外的功能或行为。在本例中,我们将创建一个名为with_refresh的装饰器,它将负责检测访问令牌是否过期,并在必要时自动刷新它。

三、实现令牌刷新逻辑

首先,我们需要定义一个refresh_access_token函数,该函数将负责与认证服务器通信以获取新的访问令牌。这个函数的实现可能会因您的具体认证流程而异,但关键是要确保它能正确处理成功和失败的情况。

接下来,我们将创建with_refresh装饰器。这个装饰器将接受一个函数作为参数,并在其内部调用该函数。在调用过程中,装饰器将检查响应的状态码,如果状态码为401(表示未授权,可能是因为令牌过期),则触发令牌刷新逻辑。

为了提高可靠性,我们可以进一步使用retrying库来自动重试刷新令牌的操作。这样,即使在网络延迟或认证服务器暂时不可用的情况下,我们也能最大限度地保证用户体验。

四、集成到实际应用中

最后,我们将展示如何将with_refresh装饰器应用到实际的API调用中。只需在需要自动刷新令牌的方法上添加@with_refresh注解,即可享受装饰器为我们带来的便利。

以下是一个完整的示例:

import time
import requests
from retrying import retry

# 定义 API 服务的基本 URL
BASE_URL = 'http://127.0.0.1:5000'
access_token = str()
refresh_token = str()


def login(uname: str, passwd: str):
    login_url = f"{BASE_URL}/login"
    data = {"username": uname, "password": passwd}
    resp = requests.post(login_url, json=data)
    if resp.status_code == 200:
        return resp.json().get("access_token"), resp.json().get("refresh_token")
    else:
        print("Login failed.")
        return None, None


@retry(stop_max_attempt_number=3, wait_fixed=2000)
def refresh_access_token():
    global access_token
    refresh_url = f"{BASE_URL}/refresh"
    headers = {
        "Authorization": f"Bearer {refresh_token}"
    }
    resp = requests.post(refresh_url, headers=headers)
    if resp.status_code == 200:
        access_token = resp.json().get("access_token")
        return True
    else:
        print("Token refresh failed.")
        return None


def with_refresh(func):
    def wrapper(*arg, **kwargs):
        try:
            resp = func(*arg, **kwargs)
            if resp.status_code == 401:
                raise Exception(resp.json().get('msg'))
            else:
                return resp
        except Exception as e:
            print(f"Error: {e}")
            new_access_token = refresh_access_token()
            if new_access_token:
                return func(*arg, **kwargs)
            else:
                print("Token refresh failed.")
                return None
    return wrapper


@with_refresh
def get_protected_data():
    headers = {"Authorization": f"Bearer {access_token}"}
    protected_url = f"{BASE_URL}/data"
    return requests.get(protected_url, headers=headers)


if __name__ == "__main__":
    access_token, refresh_token = login("test", "test")
    response = get_protected_data()
    print(response.json())
    time.sleep(62)
    response = get_protected_data()
    print(response.json())

在这个示例中,我们使用了一个装饰器 with_refresh 来处理访问令牌过期的情况。当访问受保护的数据时,如果访问令牌已过期,我们会尝试使用刷新令牌来刷新访问令牌。如果刷新成功,我们会再次尝试访问受保护的数据。如果刷新失败,我们会返回一个错误消息。

五、结论

通过本文的介绍,您已经学会了如何使用Python装饰器优雅地处理访问令牌的刷新问题。这种方法不仅提高了代码的可读性和可维护性,还确保了即使在令牌过期的情况下,用户也能获得流畅的应用体验。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

练习题(2024/5/6)

1路径总和 II 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1: 输入:root [5,4,8,11,null,13,4,7,2,null,null,5,1], target…

【数据结构】C++语言实现栈(详细解读)

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话: 知不足而奋进,望远山而前行&am…

【携程笔试题汇总】[全网首发] 2024-05-06-携程春招笔试题-三语言题解(CPP/Python/Java)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新携程近期的春秋招笔试题汇总~ 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢&#x1f49…

【网心云邀请码:KpyV3Dk7】轻松赚油费,新用户专享福利来袭!绑定设备连续在线7 天必得高额奖励

📢 各位朋友们,好消息来啦!现在注册网心云,通过我们的专属邀请码:KpyV3Dk7 ,即可享受多重新手福利,让您的闲置设备为您赚钱! 💸 立即加入,您将获得&#xff1…

代码本地化

目的 代码本地化(Localization)是指将软件应用程序中的文本、图形、声音和其他内容翻译成特定语言的过程,同时确保这些内容在目标文化中适当地呈现。本地化不仅仅是对文本进行翻译,还包括对日期、时间、数字、货币、排序顺序、文本…

生成一个好故事!StoryDiffusion:一致自注意力和语义运动预测器必不可少(南开字节)

文章链接:https://arxiv.org/pdf/2405.01434 主页:https://storydiffusion.github.io/ 对于最近基于扩散的生成模型来说,在一系列生成的图像中保持一致的内容,尤其是那些包含主题和复杂细节的图像,是一个重大挑战。本…

C/C++ BM32 合并二叉树

文章目录 前言题目解决方案一1.1 思路阐述1.2 源码 解决方案二2.1 思路阐述2.2 源码 总结 前言 树的题目大概率是要用到递归的,将一个树的问题拆分成子树的问题,不断拆分。 这题也用到了递归的思想。 题目 已知两颗二叉树,将它们合并成一颗…

腾讯地图商业授权说明一篇文章讲清楚如何操作

最近在使用腾讯地图,发现我要上架应用商店APP需要我有地图的授权书。 认真研究了一下原来腾讯地图现在要收费了,如果你打算以商业目的使用它,比如对第三方用户收费或者进行项目投标等,就需要先获取腾讯位置服务的商业授权许可。申…

网络演进技术演进:裸纤专线、SDH、MSTP+、OTN、PTN、IP-RAN

前言 文章主要介绍常见名词以及其在各自领域实现的功能价值。 01 裸纤 裸光纤(裸光纤)由运营商提供,是无中继的光纤线路,仅通过配线架连接。相比传统光纤,裸光纤提供纯粹的物理传输路径,无需额外网…

win2012磁盘空间不足,c盘正常,d盘无法写入,如何解决?

🏆本文收录于「Bug调优」专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&…

人工智能概述与入门基础简述

人工智能(AI)是计算机科学的一个分支,它致力于创建能够执行通常需要人类智能的任务的机器。这篇科普文章将全面介绍人工智能的基本概念、发展历程、主要技术、实际应用以及如何入门这一领域。 一、人工智能的定义与发展历程 人工智能的概念…

vue2实现生成二维码和复制保存图片功能(复制的同时会给图片加文字)

<template><divstyle"display: flex;justify-content: center;align-items: center;width: 100vw;height: 100vh;"><div><!-- 生成二维码按钮和输入二维码的输入框 --><input v-model"url" placeholder"输入链接" ty…

第四篇:记忆的迷宫:探索计算机存储结构的奥秘与创新

记忆的迷宫&#xff1a;探索计算机存储结构的奥秘与创新 1 引言 1.1 计算机存储系统的发展与重要性 在现代计算技术中&#xff0c;存储系统承担着非常关键的角色&#xff0c;它不仅负责信息的持久保存&#xff0c;同时确保高效的数据访问速度&#xff0c;影响着整体系统性能的…

[redis] redis为什么快

1. Redis与Memcached的区别 两者都是非关系型内存键值数据库&#xff0c;现在公司一般都是用 Redis 来实现缓存&#xff0c;而且 Redis 自身也越来越强大了&#xff01;Redis 与 Memcached 主要有以下不同&#xff1a; (1) memcached所有的值均是简单的字符串&#xff0c;red…

electron 通信总结

默认开启上下文隔离的情况下 渲染进程调用主进程方法&#xff1a; 主进程 在 main.js 中&#xff0c; 使用 ipcMain.handle&#xff0c;添加要处理的主进程方法 const { ipcMain } require("electron"); 在 electron 中创建 preload.ts 文件&#xff0c;从 ele…

getchar和putchar函数详解

getchar和putchar函数详解 1.getchar函数1.1函数概述1.2函数返回值1.3函数注意事项1.4函数的使用 2.putchar函数2.1函数概述2.2函数返回值2.3函数使用实例 1.getchar函数 1.1函数概述 从一个流中读取一个字符&#xff0c;或者从标准输入中获得一个字符 函数原型&#xff1a; …

HFSS学习-day1-T形波导的内场分析和优化设计

入门实例--T形波导的内场分析和优化设计 HFSS--此实例详细步骤1.创建项目2.设置求解类型3.设置与建模相关的一些信息设置默认的建模长度单位 4.创建T形模型的三个臂基本参数端口激励进行复制 5.创建被挖去的部分设置正确的边界条件和端口激励方式添加求解设置添加扫频项检查一下…

基于EWT联合SVD去噪

一、代码原理 &#xff08;1&#xff09;基于EWT-SVD的信号去噪算法原理 经验小波变换&#xff08;Empirical Wavelet Transform&#xff0c;EWT&#xff09;&#xff1a;EWT是一种基于信号局部特征的小波变换方法&#xff0c;能够更好地适应非线性和非平稳信号的特性。奇异值…

寻找最佳App分发平台:小猪APP分发脱颖而出

在当今移动应用市场日益饱和的环境下&#xff0c;选择一个合适的App分发平台对于开发者来说至关重要。这不仅关系到应用能否快速触达目标用户&#xff0c;还直接影响到品牌的塑造与市场份额的争夺。本文将深入探讨几大关键因素&#xff0c;帮助开发者判断哪个App分发平台最适合…

pyside6的调色板QPalette的简单应用

使用调色板需要先导入:from PySide6.QtGui import QPalette 调色板QPalette的源代码&#xff1a; class QPalette(Shiboken.Object):class ColorGroup(enum.Enum):Active : QPalette.ColorGroup ... # 0x0Normal : QPalette.ColorGrou…
最新文章