首页 > 编程问答 >在 FastAPI + JWT 身份验证中如何最好地实现 is_active ?

在 FastAPI + JWT 身份验证中如何最好地实现 is_active ?

时间:2024-07-28 12:59:46浏览次数:10  
标签:python jwt fastapi

我的用户模型有一个字段 is_active。如果为假,则说明该用户的账户被封锁。在这种情况下如何实施访问限制?我应该拒绝用户访问某些端点吗?执行此检查的最佳地点在哪里?如果 is_active = False,它是否应该在 get_current_user 依赖项中?

我的依赖项函数 get_current_user

async def get_current_user(
    db: SessionDep, token: Annotated[str, Depends(oauth2_scheme)]
) -> User:
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )

    token_data = await verify_access_token(token, credentials_exception)

    result = await db.execute(select(User).where(User.id == token_data.id))
    user = result.scalar_one_or_none()

    if user is None:
        raise credentials_exception


    return user

你思路正确,在 get_current_user 依赖项中检查 is_active 是最佳实践。这样可以集中处理所有身份验证和授权逻辑,并在用户未激活时阻止对所有受保护路由的访问。

以下是改进后的代码示例:

from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from sqlalchemy.orm import Session
from jose import JWTError, jwt

# ... 其他导入 ...

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

async def get_current_user(
    db: Session, token: str = Depends(oauth2_scheme)
) -> User:
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        user_id: str = payload.get("sub")
        if user_id is None:
            raise credentials_exception
    except JWTError:
        raise credentials_exception

    user = db.query(User).filter(User.id == user_id).first()
    if user is None:
        raise credentials_exception

    # 检查用户是否激活
    if not user.is_active:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Inactive user")

    return user

# 使用依赖项保护路由
@app.get("/items/", response_model=List[Item])
async def read_items(current_user: User = Depends(get_current_user)):
    # current_user 将始终是激活的用户
    # ... 路由逻辑 ...

在这个改进版本中:

  1. get_current_user 中检查 is_active : 在成功获取用户后,我们添加了一个检查 user.is_active 的条件。如果用户未激活 ( False ),则抛出一个 403 Forbidden 错误。
  2. 集中处理错误 : 我们使用 HTTPException 来处理未经授权和禁止访问的错误,提供清晰的错误信息。
  3. 受保护的路由 : 所有需要身份验证和授权的路由都应该使用 Depends(get_current_user) 来获取当前用户。这确保只有激活的用户才能访问这些路由。

通过这种方式,你可以有效地限制未激活用户的访问,并在尝试访问受保护资源时提供明确的错误信息。

标签:python,jwt,fastapi
From: 78802976

相关文章

  • AttributeError:'int'对象没有属性'index'(python)
    我正在Python上进行“猜单词”,但我无法弄清楚这个错误。AttributeError:'int'objecthasnoattribute'index'(python)它在线上给了我一个错误letterIndex=word.index(guess)defcheckLetter(word):blanks='_'*len(str(word))print('W......
  • 尝试在Python中使用for循环来输出大于或等于序列中的数字
    这是我的Python代码:largest_so_far=-1print('before',largest_so_far)forthe_numin[9,41,12,3,74,15]:ifthe_num>largest_so_far:largest_so_far=the_numprint(largest_so_far,'isbiggerthan',the_num)......
  • 如何在 wxPython 的 for 循环中添加文本输入框?
    我是wxPython的新手,正在开发一个带有GUI的基本程序,让用户标记图像。现在,当用户单击“导入”按钮时,他们可以选择一个目录。然后,代码使用matplotlib在for循环中显示该目录中的每个图像。但是,我不知道如何在for循环中访问用户输入。这就是该函数现在的样子:importmatplo......
  • 【Python】字母 Rangoli 图案
    一、题目YouaregivenanintegerN.YourtaskistoprintanalphabetrangoliofsizeN.(RangoliisaformofIndianfolkartbasedoncreationofpatterns.)Differentsizesofalphabetrangoliareshownbelow:#size3----c------c-b-c--c-b-a-b-c--c......
  • python 闭包、装饰器
    一、闭包:1.外部函数嵌套内部函数 2.外部函数返回内部函数 3.内部函数可以访问外部函数局部变量         闭包(Closure)是指在一个函数内部定义的函数,并且内部函数可以访问外部函数的局部变量,即使外部函数已经执行完毕,这种现象称为闭包。在Python中,闭包常常用......
  • 掌握 IPython %%time 魔法命令:高效测量代码块执行时间
    引言在编程和数据分析中,了解代码的执行时间是优化性能的关键步骤。IPython,作为一个强大的交互式计算环境,提供了多种工具来帮助用户测量和优化代码。其中,%%time魔法命令是IPython中用来测量代码块执行时间的便捷工具。本文将详细介绍%%time魔法命令的使用方法,并通过一......
  • 探索 IPython 中的 %%javascript 魔法命令:运行 JavaScript 代码的秘籍
    引言IPython是一个强大的交互式计算环境,它不仅支持Python语言,还通过各种魔法命令扩展了其功能。其中,%%javascript魔法命令是IPython扩展中一个非常有趣的特性,它允许用户在IPython环境中直接运行JavaScript代码。这对于需要在数据科学和科学计算中使用JavaScript......
  • pythonasm库分析,看看你和自学编程小学生的差距
    下面是pythonasm.asm库的源代码fromkeystoneimport*fromcapstoneimport*assembly_instructions=[]#储存汇编指令的列表#汇编指令写入列表defmov(reg1,reg2):assembly_instructions.append(f"mov{reg1},{reg2}")defdb(value):assembly_instructio......
  • 【Python系列】Python 中的垃圾收集:深入理解与实践
    ......
  • Python酷库之旅-第三方库Pandas(050)
    目录一、用法精讲181、pandas.Series.var方法181-1、语法181-2、参数181-3、功能181-4、返回值181-5、说明181-6、用法181-6-1、数据准备181-6-2、代码示例181-6-3、结果输出182、pandas.Series.kurtosis方法182-1、语法182-2、参数182-3、功能182-4、返回值1......