PyJWT Subject must be a string

今天clone一个python项目,作为新手来学习,结果跑起来一直报错,报错内容如下:

127.0.0.1 - - [22/Mar/2025 09:32:03] "GET /static/component/pear/module/extends/popup.js?v=4.0.0 HTTP/1.1" 304 -
127.0.0.1 - - [22/Mar/2025 09:32:03] "GET /api/v1/user/profile HTTP/1.1" 403 -
127.0.0.1 - - [22/Mar/2025 09:32:03] "GET /static/config/pear.config.json HTTP/1.1" 304 -
127.0.0.1 - - [22/Mar/2025 09:32:03] "GET /api/v1/menu?fresh=0.9533041415950494 HTTP/1.1" 403 -
127.0.0.1 - - [22/Mar/2025 09:32:03] "GET /view/analysis/index.html HTTP/1.1" 200 -
127.0.0.1 - - [22/Mar/2025 09:32:03] "GET /static/admin/images/logo.png HTTP/1.1" 304 -
127.0.0.1 - - [22/Mar/2025 09:32:03] "GET /static/admin/images/avatar.jpg HTTP/1.1" 304 -
127.0.0.1 - - [22/Mar/2025 09:32:03] "GET /static/admin/css/other/analysis.css HTTP/1.1" 304 -

日志什么都没有打印,就提示user/profile接口403错误,于是研究这个接口,接口内容如下,而且打断点无反应,说明还没到断点就出现了

@user_api.get("/user/profile")
@jwt_required()
def user_profile():
    return {
        "code": 0,
        "msg": "获取个人数据成功",
        "data": current_user.json(),
    }

由于在浏览器上看不见返回信息,然后我换postman,这个可以看见报错内容{"msg": "Subject must be a string"},拿着Subject must be a string的错误,通过AI的帮助,找到了问题所在,那就是@jwt_required()有问题
在这里插入图片描述

意思就是:jwt中有一个sub字段必须是字符串,于是给jwt解密,果不其然,找到问题!!
在这里插入图片描述

分析代码,可以看见,在绑定user_identity_loader的时候,使用的是id,目前我这个id是数字,所以不对,我直接转成字符串,就解决问题。

@jwt.user_identity_loader
def user_identity_lookup(user):
    return user.id
    # return str(user.id) 正确代码


@jwt.user_lookup_loader
def user_lookup_callback(_jwt_header, jwt_data):
    identity = jwt_data["sub"]
    return UserORM.query.filter(UserORM.id == identity).one_or_none()

虽然转成字符串就可以解决我的问题,这也不能算是代码错误,还是跟业务有关,记录一下分析问题的过程吧!!!最后我这个PyJWT版本2.10.1

①pyjwt版本问题,可能之前是支持数字的,然后我的版本较,淘汰了那种写法。
②可能是切换数据库导致的,比如之前是mongodb,生成的id就是字符串。
③之前的数据库id是手动控制的,现在被我改成自增。

PyJWT是一个Python库,用于处理JSON Web Tokens(JWT)。它主要用于安全地在客户端和服务端之间传输信息,例如用户登录验证。如果你想在SQLite数据库中存储用户的JWT令牌并进行登录验证,可以按照以下步骤操作: 1. **安装依赖**: 首先,确保已经安装了`PyJWT`, `SQLAlchemy`(ORM工具用于操作SQLite)以及可能需要的加密库,如`cryptography`(如果你计划对JWT进行加密)。 ```bash pip install pyjwt sqlalchemy cryptography ``` 2. **模型设计**: 创建一个User模型,包含一个JWT Secret(用于签发和验证JWT)和一个SQLite字段来存储JWT。 ```python from sqlalchemy import Column, String, create_engine from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(String, primary_key=True) jwt_secret = Column(String) token = Column(String) # 存储已签发的JWT ``` 3. **登录认证**: 用户登录时,生成JWT,并将其加密存储到数据库。同时存储JWT Secret以备后续验证。 ```python def generate_jwt(user_id, secret): payload = {'sub': user_id} encoded_jwt = jwt.encode(payload, secret, algorithm='HS256') return encoded_jwt, secret def register_user_and_login(user_data): new_user = User(id=user_data['id'], jwt_secret=generate_jwt_secret()) db.session.add(new_user) db.session.commit() # 返回生成的JWT和秘钥 return new_user.token, new_user.jwt_secret ``` 4. **验证登录**: 当接收JWT请求时,从数据库查找对应的用户,然后解密并验证JWT。 ```python def validate_jwt(token, user_secret): try: decoded_token = jwt.decode(token, user_secret, algorithms=['HS256']) if 'sub' in decoded_token and decoded_token['sub'] == get_user_id_from_db(token): # 根据JWT中的信息获取用户ID return True except jwt.exceptions.InvalidTokenError: pass return False ``` 5. **授权访问**: 在需要的地方,检查请求头或cookie的JWT是否有效。 ```python def protected_endpoint(): auth_header = request.headers.get('Authorization', '') if not validate_jwt(auth_header.split(' '), get_secret_from_db()): raise HTTPException(status_code=401, detail="Unauthorized") # 接下来的代码仅对授权用户开放 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值