怎么在Python Flask中集成JWT实现无状态身份认证

风静同学_9173

风静同学_9173

2026-10-17

608人浏览

原创

直接用PyJWT因其轻量、可控性强,能直面密钥管理、exp/nbf校验、算法选择等核心约束;而Flask-JWT已停更,Flask-JWT-Extended则默认行为过多易掩盖逻辑细节。

怎么在python flask中集成jwt实现无状态身份认证

为什么直接用 PyJWT 而不是 Flask-JWT 或 Flask-JWT-Extended?

Flask-JWT 已停止维护,Flask-JWT-Extended 功能强但引入大量默认行为(比如自动处理 Authorization header、强制使用 get_jwt_identity()),容易掩盖认证逻辑细节。实际项目中,你更需要明确控制 token 签发、校验、刷新和失效逻辑——尤其是当要对接前端 cookie + httpOnly、或支持多签发方、或自定义 claim 结构时。

PyJWT 更轻量,API 清晰,且能让你直面 JWT 的核心约束:签名密钥管理、过期时间校验、算法选择、时钟偏移容忍等。

  • 必须用 HS256 或 RS256,别用 none 算法(存在漏洞)
  • exp 和 nbf 字段需显式校验,PyJWT 默认不校验 nbf
  • 密钥不能硬编码在代码里,应从环境变量读取:os.getenv("SECRET_KEY")

如何生成带用户信息的 JWT 并安全返回?

签发 token 时,只放最小必要字段(如 user_id、role),避免泄露敏感信息;同时设置短有效期(如 15 分钟),配合 refresh token 机制。

import jwt
import datetime
import os
<p>def create_access_token(user_id: int, role: str = "user") -> str:
payload = {
"user_id": user_id,
"role": role,
"exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=15),
"iat": datetime.datetime.utcnow(),
"jti": str(uuid.uuid4()),  # 防重放,需存入 Redis 校验
}
return jwt.encode(payload, os.getenv("SECRET_KEY"), algorithm="HS256")
</p>
  • 别把密码、邮箱、手机号放进 payload —— token 可被 base64 解码,无加密
  • exp 必须设,否则 token 永不过期;iat 建议加上,便于调试签发时间
  • 若需防 token 重放,用 jti 字段 + Redis 存储已用 jti(签发时写入,校验前查重)

如何在 Flask 路由中校验 JWT 并提取用户身份?

不要在每个视图函数里重复写解码逻辑。用 @app.before_request 或自定义装饰器统一拦截,把解析结果挂到 g 对象上,后续视图可直接访问 g.current_user_id。

Claw Code Suite (Python-Only Edition)
Claw Code Suite (Python-Only Edition)

仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...

下载
from flask import request, g, jsonify
from functools import wraps
<p>def require_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth_header = request.headers.get("Authorization")
if not auth_header or not auth_header.startswith("Bearer "):
return jsonify({"error": "Missing or invalid Authorization header"}), 401</p><pre class="brush:php;toolbar:false;">    token = auth_header[7:]
    try:
        payload = jwt.decode(
            token,
            os.getenv("SECRET_KEY"),
            algorithms=["HS256"],
            options={"require": ["exp", "iat"], "verify_exp": True},
        )
        g.current_user_id = payload["user_id"]
        g.current_role = payload["role"]
    except jwt.ExpiredSignatureError:
        return jsonify({"error": "Token expired"}), 401
    except jwt.InvalidTokenError:
        return jsonify({"error": "Invalid token"}), 401
    return f(*args, **kwargs)
return decorated

使用示例

@app.route("/profile") @require_auth def profile(): return jsonify({"user_id": g.current_user_id, "role": g.current_role})

  • 必须检查 Authorization header 格式,空值、格式错误都应拒掉
  • options={"verify_exp": True} 显式开启过期校验(PyJWT 2.x+ 默认开启,但老版本需手动设)
  • 别用 try/except Exception,精确捕获 jwt.ExpiredSignatureError 和 jwt.InvalidTokenError

cookie + httpOnly 方式传 token 时要注意什么?

前端用 fetch 发请求时,默认不带 cookie,需设 credentials: "include";后端则要用 set_cookie 设置 httpOnly=True、secure=True(HTTPS 环境)、samesite="Lax"。

@app.route("/login", methods=["POST"])
def login():
    # ... 验证用户名密码
    token = create_access_token(user.id)
    response = jsonify({"msg": "logged in"})
    response.set_cookie(
        "access_token",
        token,
        httponly=True,
        secure=True,  # 生产必须开
        samesite="Lax",
        max_age=900,  # 15 分钟,与 token exp 一致
    )
    return response
  • cookie 名别叫 token 或 jwt,避免被通用扫描规则误报
  • max_age 应 ≤ token 的 exp 时长,否则 cookie 过期后前端仍可能发旧 token
  • 若前端是跨域 SPA(如 React 在 localhost:3000),需同时配 Flask 的 CORS 支持 credentials

最易被忽略的是时钟同步问题:服务器和客户端系统时间偏差超过 60 秒,exp/nbf 校验就会失败。生产环境务必用 NTP 同步时间,开发时可在 jwt.decode 中加 leeway=60 容忍 1 分钟偏差。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

python flask

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1751

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4504

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1729

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

26497

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3207

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3227

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1183

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2503

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习