Flask 学习-28.flask_jwt_extended插件 JWT 中存储额外数据(additional_claims)

袁单鹗
2023-12-01

前言

在访问令牌中存储其他信息,以后可以在受保护的视图中访问这些信息。这可以使用additional_claims 带有create_access_token()or create_refresh_token()函数的参数来完成。
get_jwt() 函数在受保护的路径中获取额外的数据。

additional_claims参数使用

重要的是要记住 JWT 没有加密,任何有权访问它的人都可以轻松解码 JWT 的内容。因此,您永远不应该将任何敏感信息放在 JWT 中。
官方文档示例

from flask import Flask
from flask import jsonify
from flask import request

from flask_jwt_extended import create_access_token
from flask_jwt_extended import get_jwt
from flask_jwt_extended import jwt_required
from flask_jwt_extended import JWTManager

app = Flask(__name__)

app.config["JWT_SECRET_KEY"] = "super-secret"  # Change this!
jwt = JWTManager(app)


@app.route("/login", methods=["POST"])
def login():
    username = request.json.get("username", None)
    password = request.json.get("password", None)
    if username != "test" or password != "test":
        return jsonify({"msg": "Bad username or password"}), 401

    # You can use the additional_claims argument to either add
    # custom claims or override default claims in the JWT.
    additional_claims = {"aud": "some_audience", "foo": "bar"}
    access_token = create_access_token(username, additional_claims=additional_claims)
    return jsonify(access_token=access_token)


# In a protected view, get the claims you added to the jwt with the
# get_jwt() method
@app.route("/protected", methods=["GET"])
@jwt_required()
def protected():
    claims = get_jwt()
    return jsonify(foo=claims["foo"])


if __name__ == "__main__":
    app.run()

或者,您可以使用additional_claims_loader() 装饰器注册一个回调函数,该函数将在创建新 JWT 时调用,并返回一个声明字典以添加到该令牌。
在同时使用additional_claims_loader()和 additional_claims参数的情况下,两个结果将合并在一起,并与additional_claims参数提供的数据相关联。

# Using the additional_claims_loader, we can specify a method that will be
# called when creating JWTs. The decorated method must take the identity
# we are creating a token for and return a dictionary of additional
# claims to add to the JWT.
@jwt.additional_claims_loader
def add_claims_to_access_token(identity):
     return = {
         "aud": "some_audience",
         "foo": "bar",
         "upcase_name": identity.upper(),
     }

使用示例

比如我们想在用户登录的时候,加一个is_admin 的判断, 需在生成token之前加一些参数

        if user.username == 'admin':
            additional_claims = {"is_admin": True}
        else:
            additional_claims = {"is_admin": False}
        access_token = create_access_token(identity=user, additional_claims=additional_claims)

在视图函数中用 get_jwt() 方法获取额外数据

class UserInfo(Resource):

    @jwt_required()
    def get(self):
        """根据token 解析用户username"""
        print(f"xxxxxxxxxxxxxx: {current_user}")
        # get_jwt() 获取额外参数
        claims = get_jwt()
        print(f"xxxxxxxxxxxxxx: {claims}")
        return {
            "msg": 'success',
            "data": {
                "id": current_user.id,
                "username": current_user.username
            }
        }


# 注册
api.add_resource(UserInfo, '/api/v1/userinfo')

claims 获取到的数据格式如下

{
'fresh': False, 
'iat': 1661999958, 
'jti': '24e267e1-3959-4b86-850d-ea5002991063', 
'type':'access', 
'sub': 5, 
'nbf': 1661999958, 
'exp': 1662003558, 
'is_admin': False
}

get_jwt()用于获取access_token存储的信息,在旧版本中使用的是get_jwt_claims(), 功能一样。

 类似资料: