使用FastAPIJWT构建Web应用的鉴权系统

在Web应用开发中,鉴权系统是必不可少的一个环节。FastAPIJWT是使用JSON Web Token(以下简称JWT)在FastAPI中构建鉴权系统的一种简单、快速但功能强大的方法。JWT是一种开放标准(RFC 7519),用于在网络应用之间传递声明。JWT中的信息使用JSON对象进行编码,以数字签名方式进行验证。

一、在FastAPI中使用FastAPIJWT

在开始使用FastAPIJWT之前,需要使用pip安装FastAPI和FastAPIJWT库:

pip install fastapi
pip install fastapi-jwt-auth

接下来,我们需要在FastAPI应用程序中添加FastAPIJWT的配置项和路由以启用鉴权系统。

在应用程序的主文件中,导入FastAPI、FastAPIJWT库并创建应用程序实例:

from fastapi import FastAPI
from fastapi_jwt_auth import AuthJWT

app = FastAPI()

接下来,我们需要配置FastAPIJWT并在应用程序中注册路由以处理jwt相关的请求。这里我们使用AuthJWT装饰器,该装饰器接受应用程序实例作为参数。配置中我们需要设置SECRET_KEY、ACCESS_TOKEN_EXPIRE_MINUTES和ALGORITHM参数,在路由中我们可以通过AuthJWT.current_user()方法获取当前用户的信息:

# 必须设置的Secret Key以进行JWT加密和解密
app.config["SECRET_KEY"] = "your-secret-key"

# JWT过期时间(分钟)
app.config["ACCESS_TOKEN_EXPIRE_MINUTES"] = 30

# JWT算法
app.config["ALGORITHM"] = "HS256"

# JWT鉴权路由
@app.post("/login")
def login(auth: AuthJWT = Depends()):
    # 获取用户名和密码
    username = form_data.username
    password = form_data.password

    # 验证用户
    is_authenticated = verify_user(username, password)
    if is_authenticated:
        # 创建JWT令牌
        access_token = auth.create_access_token(subject=username)
        return {"access_token": access_token}
    else:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

@app.get("/protected")
def protected_route(user: User = Depends(get_current_user)):
    return {"message": "Hello, {0}!".format(user.username)}

在上面的示例中,我们使用了两个路由:/login和/protected。在/login路由中,我们获取用户的用户名和密码,并验证用户身份。如果用户身份验证成功,则调用AuthJWT.create_access_token()方法生成JWT令牌并返回给客户端。在/protected路由中,我们使用@Depends装饰器中的get_current_user方法来保护该路由。

二、使用FastAPIJWT保护路由

在上一节中,我们已经使用FastAPIJWT创建了鉴权系统。在本节中,我们将使用FastAPIJWT来保护我们的路由,仅允许经过身份验证的用户访问。

首先,我们需要创建一个获取当前用户的函数(也称为依赖项),该函数将在路由中使用。

from fastapi_jwt_auth import AuthJWTfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentialsfrom fastapi import Dependsjwt_scheme = HTTPBearer()# 获取当前用户的函数def get_current_user(auth: HTTPAuthorizationCredentials = Depends(jwt_scheme), jwt: AuthJWT = Depends()):    try:        # 调用AuthJWT.verify_token()方法验证token并返回用户信息        jwt.verify_token(auth.credentials)        current_user = jwt.get_jwt_subject()    except:        # 验证失败时抛出HTTPException        raise HTTPException(status_code=401, detail="Invalid token")    return {"username": current_user}

在上述get_current_user方法中,我们使用@Depends装饰器指定了两个依赖项:auth和jwt。其中auth参数的值为FastAPI的HTTPBearer OAuth类型,用于获取HTTP头部中的JWT密码。jwt参数的值为AuthJWT实例,用于验证JWT密码和获取JWT主题(即用户标识符)。如果验证成功,则返回包含用户名的JSON对象。如果验证失败,则返回401 UnauthorizedHTTPException。接下来,我们可以在要保护的路由中使用该get_current_user方法。

# 保护路由
@app.get("/protected")
def protected_route(user: User = Depends(get_current_user)):
    return {"message": "Hello, {0}!".format(user.username)}

在上述示例中,我们使用fastapi的@Depends装饰器来指定get_current_user方法作为get_protected_route路由的依赖项。如果用户通过身份验证,则返回包含用户信息的JSON对象。如果用户未通过身份验证,则返回401 Unauthorized HTTPException。

三、使用Refresh Token实现JWT自动续期

JWT的过期时间是有限的。但是,如果用户一直在使用应用程序,他们可能希望在该时间段内自动续订他们的JWT。为了实现这一点,FastAPIJWT提供了一个自动续订机制,该机制使用Refresh Token。

在FastAPIJWT中,Refresh Token是一种与访问令牌(access token)相关的短暂的JWT。Refresh Token创建后的短暂有效期内可以用来获取新的访问令牌,从而允许用户无缝延长访问令牌的有效期。

要使用Refresh Token,请指定一个可选的REFRESH_TOKEN_EXPIRE_MINUTES选项,该选项指定Refresh Token的过期时间。以下是实现JWT自动续期的示例:

# JWT自动续订路由
@app.post("/refresh")
def refresh_token(authorize: AuthJWT = Depends()):
    # 验证Refresh Token
    authorize.jwt_refresh_token_required()

    # 创建新的AccessToken
    current_user = authorize.get_jwt_subject()
    new_access_token = authorize.create_access_token(subject=current_user)

    # 返回新的AccessToken
    return {"access_token": new_access_token, "refresh_token": authorize.create_refresh_token(subject=current_user)}

在上述示例中,我们使用AuthJWT装饰器和create_refresh_token()方法创建了Refresh Token。如果Refresh Token存在且有效,则可以调用create_access_token()方法创建新的Access Token。

此时,我们需要相应地更新前一节中的login()路由和get_current_user()函数。

# Login路由
@app.post("/login")
def login(form_data: LoginForm, authorize: AuthJWT = Depends()):
    # 获取用户名和密码
    username = form_data.username
    password = form_data.password

    # 验证用户
    is_authenticated = verify_user(username, password)
    if is_authenticated:
        # 创建JWT令牌和Refresh Token
        access_token = authorize.create_access_token(subject=username)
        refresh_token = authorize.create_refresh_token(subject=username)
        return {"access_token": access_token, "refresh_token": refresh_token}
    else:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

# 获取当前用户的函数
def get_current_user(authorize: AuthJWT = Depends()):
    try:
        # 调用AuthJWT.refresh_jwt_token()方法来刷新Token
        authorize.jwt_refresh_token_required()
        authorize.refresh_jwt_token()
        current_user = authorize.get_jwt_subject()
    except:
        # 验证失败时抛出HTTPException
        raise HTTPException(status_code=401, detail="Invalid token")

    return {"username": current_user}

在上述示例中,我们使用AuthJWT.refresh_jwt_token()方法来刷新JWT。如果Refresh Token有效,则会自动创建新的Access Token并返回给客户端。

四、结语

到目前为止,我们已经使用FastAPIJWT构建了一个功能齐全的Web应用程序鉴权系统,实现了访问控制和自动续订功能。FastAPIJWT是使用FastAPI创建鉴权系统的最佳选择之一,因为它结合了FastAPI的速度和易用性,以及JWT提供的强大的安全保障。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/253894.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-14 02:19
下一篇 2024-12-14 02:19

相关推荐

  • Deepin系统分区设置教程

    本教程将会详细介绍Deepin系统如何进行分区设置,分享多种方式让您了解如何规划您的硬盘。 一、分区的基本知识 在进行Deepin系统分区设置之前,我们需要了解一些基本分区概念。 …

    编程 2025-04-29
  • Java任务下发回滚系统的设计与实现

    本文将介绍一个Java任务下发回滚系统的设计与实现。该系统可以用于执行复杂的任务,包括可回滚的任务,及时恢复任务失败前的状态。系统使用Java语言进行开发,可以支持多种类型的任务。…

    编程 2025-04-29
  • 如何在树莓派上安装Windows 7系统?

    随着树莓派的普及,许多用户想在树莓派上安装Windows 7操作系统。 一、准备工作 在开始之前,需要准备以下材料: 1.树莓派4B一台; 2.一张8GB以上的SD卡; 3.下载并…

    编程 2025-04-29
  • Python Web开发第三方库

    本文将介绍Python Web开发中的第三方库,包括但不限于Flask、Django、Bottle等,并讨论它们的优缺点和应用场景。 一、Flask Flask是一款轻量级的Web…

    编程 2025-04-29
  • Web程序和桌面程序的区别

    Web程序和桌面程序都是进行软件开发的方式,但是它们之间存在很大的区别。本文将从多角度进行阐述。 一、运行方式 Web程序运行于互联网上,用户可以通过使用浏览器来访问它。而桌面程序…

    编程 2025-04-29
  • 分销系统开发搭建

    本文主要介绍如何搭建一套完整的分销系统,从需求分析、技术选型、开发、部署等方面进行说明。 一、需求分析 在进行分销系统的开发之前,我们首先需要对系统进行需求分析。一般来说,分销系统…

    编程 2025-04-29
  • 云盘开源系统哪个好?

    本文将会介绍几种目前主流的云盘开源系统,从不同方面对它们做出分析比较,以此来确定哪个云盘开源系统是最适合您的。 一、Seafile Seafile是一款非常出色的云盘开源系统,它的…

    编程 2025-04-28
  • EulerOS V2R7:企业级开发首选系统

    本文将从多个方面为您介绍EulerOS V2R7,包括系统简介、安全性、易用性、灵活性和应用场景等。 一、系统简介 EulerOS V2R7是一个华为公司开发的企业级操作系统,该系…

    编程 2025-04-28
  • 基于Python点餐系统的实现

    在当前瞬息万变的社会,餐饮行业也在加速发展,如何更好地为客户提供更加便捷、高效、个性化的点餐服务,成为每个餐饮企业需要思考的问题。本文以基于Python的点餐系统为例,通过优化用户…

    编程 2025-04-28
  • Python操作Web页面

    本文将从多个方面详细介绍Python操作Web页面的技巧、方法和注意事项。 一、安装必要的库 在Python中操作Web页面,需要用到一些第三方库。 pip install req…

    编程 2025-04-28

发表回复

登录后才能评论