You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Flask应用JWT处理逻辑及客户端传入令牌的校验相关问题

Flask 服务端JWT校验完整处理流程

一、整体处理步骤

  • 第一步:提取请求头中的令牌
    首先要从Authorization请求头里把JWT摘出来,规范格式是Bearer <token>,所以要做字符串切割,去掉前缀Bearer 拿到纯token字符串,还要处理头不存在、格式不对的情况,直接返回401未授权。
  • 第二步:令牌格式基础校验
    先判断拿到的字符串是不是符合JWT的三段式结构(头.载荷.签名),缺段、格式非法直接返回401。
  • 第三步:核心有效性校验
    这步不是只校验secret_key这么简单,要校验几个核心维度:
    1. 签名合法性:用服务端保存的secret_key对前两段重新加密,和第三段签名做比对,不一致说明token被篡改,直接无效。
    2. 过期时间校验:校验载荷里的exp字段,当前时间已经超过exp值的话,token已过期,返回401。
    3. 生效时间校验(可选):如果载荷里加了nbf(not before)字段,要校验当前时间是否晚于nbf,早于的话token还没生效。
    4. 发行方/受众校验(可选):如果生成时加了iss(发行方)、aud(受众)字段,也要对应校验匹配,避免其他服务签发的token被滥用。
  • 第四步:载荷信息提取与业务校验
    校验通过后,从载荷里把用户ID、角色等自定义信息取出来,还要做业务层校验,比如用户是否还存在、是否被封禁、权限是否匹配当前接口要求,没问题再放行到业务逻辑。

二、具体实现方式

1. 基于Flask-JWT-Extended扩展的实现(推荐,无需手动造轮子)

首先安装扩展:pip install flask-jwt-extended
核心代码示例:

from flask import Flask, jsonify
from flask_jwt_extended import JWTManager, jwt_required, get_jwt_identity

app = Flask(__name__)
# 配置secret_key,必须和生成token时的密钥一致
app.config["JWT_SECRET_KEY"] = "your-secret-key-never-expose-in-production"
jwt = JWTManager(app)

# 需要校验token的接口直接加@jwt_required()装饰器即可,扩展会自动完成上面所有校验步骤
@app.route("/protected", methods=["GET"])
@jwt_required()
def protected():
    # 直接获取载荷里的用户标识
    current_user = get_jwt_identity()
    return jsonify(logged_in_as=current_user), 200

扩展已经默认做了签名校验、过期校验,要是需要自定义校验规则,比如校验用户状态,可以用@jwt.token_in_blocklist_loader装饰器实现黑名单校验,或者自定义回调函数。

2. 原生手动校验实现(适合理解原理)

可以用PyJWT库实现:pip install pyjwt
代码示例:

import jwt
from flask import request, jsonify

SECRET_KEY = "your-secret-key-never-expose-in-production"

def verify_jwt():
    # 提取token
    auth_header = request.headers.get("Authorization")
    if not auth_header or not auth_header.startswith("Bearer "):
        return None, "无效的Authorization头"
    token = auth_header.split(" ")[1]
    try:
        # 校验核心参数,verify_signature默认开启,会自动用secret_key校验签名
        payload = jwt.decode(
            token,
            SECRET_KEY,
            algorithms=["HS256"],
            # 自动校验exp、nbf等字段,不需要自己写时间判断
            options={"verify_exp": True}
        )
        return payload, None
    except jwt.ExpiredSignatureError:
        return None, "令牌已过期"
    except jwt.InvalidSignatureError:
        return None, "令牌签名无效"
    except jwt.InvalidTokenError:
        return None, "无效令牌"

# 接口中使用
@app.route("/protected", methods=["GET"])
def protected():
    payload, err = verify_jwt()
    if err:
        return jsonify({"msg": err}), 401
    # 后续业务逻辑
    return jsonify(logged_in_as=payload.get("user_id")), 200

三、常见注意事项

  • 不是只校验secret_key就可以:只校验签名只能保证token没被篡改,但没法判断token是否过期、是否是发给当前服务的,还有业务层面的用户状态也需要校验。
  • 生产环境注意:secret_key要存在环境变量里,不要硬编码到代码里;敏感信息不要放到JWT载荷里,因为载荷是base64编码的,任何人拿到token都可以解码看到内容。

内容的提问来源于stack exchange,提问作者max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:27:02