📜  需要登录 fastapi (1)

📅  最后修改于: 2023-12-03 14:58:43.404000             🧑  作者: Mango

需要登录 FastAPI

如果您正在使用 FastAPI 构建 Web 应用程序,很可能需要在某些情况下要求用户进行身份验证。这就是为什么 FastAPI 提供了一个轻松的方式来实现访问控制,即需要登录功能。

在 FastAPI 中,您可以使用 OAuth2 身份验证或使用 JWT(JSON Web Tokens)进行身份验证。不管您使用哪种方式,都需要明确哪些端点需要登录并对其进行保护。

在本文中,我们将讨论如何在 FastAPI 中实现需要登录的功能,以及在这方面需要注意的事项。

OAuth2 身份验证

OAuth2 是一种授权协议,允许应用程序代表用户访问受保护的资源。在 FastAPI 中,您可以使用 OAuth2 身份验证来验证用户的身份并授权他们权限访问你的经过身份验证的端点。

以下是使用 OAuth2 身份验证需要注意的事项:

  1. 需要设置授权服务器

您需要设置一个授权服务器以进行用户身份验证,并颁发访问令牌。您可以使用现成的授权服务器,如 Google、Facebook 或 GitHub,也可以自行搭建授权服务器。

  1. 需要实现 OAuth2Schema

您需要实现 OAuth2Schema 以定义您的 OAuth2 认证方案。此方案将描述访问令牌、作用域和未授权的响应等内容。

以下是一个实现 OAuth2Schema 的示例:

from fastapi import FastAPI
from fastapi.security import OAuth2AuthorizationCodeBearer

app = FastAPI()

oauth2_scheme = OAuth2AuthorizationCodeBearer(
    authorizationUrl="https://your-auth-server.com/auth",
    tokenUrl="https://your-auth-server.com/token",
    scopes={
        "profile": "Read your profile information",
        "items": "Read items"
    }
)

@app.get("/items/")
async def read_items(oauth2: oauth2_scheme):
    return {"message": "Welcome to the OAuth2 authenticated endpoint."}

在此示例中,我们定义了一个 OAuth2AuthorizationCodeBearer 对象。这个对象需要知道授权服务器的授权 URL 和令牌 URL,以及它所支持的作用域(在此示例中,我们支持 profile 和 items 作用域)。

然后,我们在 /items/ 路径下装饰了一个函数,并声明一个 oauth2 参数。此参数将使用OAuth2AuthorizationCodeBearer模型来验证身份和令牌,如果验证成功,函数将返回一条欢迎消息。

3.需要实现登陆页面

用户将重定向到您的登录页面进行身份验证。您需要实现此登录页面并为用户提供一个 UI,以允许他们输入其凭据,并通过授权服务器进行身份验证。

以下是一个实现 OAuth2 登录页面的示例:

<html>
  <head>
    <title>Login</title>
  </head>
  <body>
    <form method="post" action="https://your-auth-server.com/auth">
      <input type="hidden" name="response_type" value="code">
      <input type="hidden" name="client_id" value="your-client-id">
      <input type="hidden" name="redirect_uri" value="https://yoursite.com/login/callback">
      <input type="hidden" name="scope" value="profile items">
      <label for="username">Username:</label>
      <input type="text" name="username">
      <br><br>
      <label for="password">Password:</label>
      <input type="password" name="password">
      <br><br>
      <input type="submit" value="Login">
    </form>
  </body>
</html>

在此示例中,我们创建了一个基本的 HTML 表单,用于用户输入其凭据。一旦用户填写了凭据,并单击登录按钮,他们将重定向到授权服务器以进行身份验证。

JWT 身份验证

JWT(JSON Web Tokens)是一种用于验证和授权的开放标准。它允许您将用户身份存储在有状态的令牌中,以便您可以在服务器端快速验证它。

以下是使用 JWT 身份验证需要注意的事项:

  1. 需要实现 JWT

您需要使用 PyJWT 库实现 JWT(JSON Web Tokens)。在以下示例中,我们使用 PyJWT 来对令牌进行编码和解码:

import jwt
from fastapi import FastAPI

app = FastAPI()

JWT_SECRET = "your-secret"

@app.get("/items/")
async def read_items(token: str):
    try:
        payload = jwt.decode(token, JWT_SECRET, algorithms=["HS256"])
    except jwt.exceptions.DecodeError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token",
            headers={"WWW-Authenticate": "Bearer"},
        )

    return {"message": f"Welcome, {payload['username']}"}

在此示例中,我们定义了一个 JWT_SECRET 变量并将其用作令牌的密钥。然后,在 /items/ 路径下装饰了一个函数,并声明一个 token 参数。此参数将使用默认的字符串类型来接收 JWT 令牌。

接着,我们使用 PyJWT 库的 jwt.decode() 方法来解码令牌,并将解码后的负载存储在 payload 变量中。如果解码失败,我们会引发一个 HTTPException 异常,并将错误消息发送回客户端。

最后,我们将 payload 变量中的用户名作为欢迎消息的一部分返回给客户端。

  1. 需要设置有效期限

您需要设置 JWT 令牌的有效期限。默认情况下,JWT 令牌将永久有效。如果您想使令牌在一段时间后失效,可以将过期时间(exp)字段添加到令牌的负载中。

以下是一个设置 JWT 令牌有效期限的示例:

from datetime import datetime, timedelta
from fastapi import FastAPI
import jwt

app = FastAPI()

JWT_SECRET = "your-secret"

@app.get("/login/")
async def login(username: str, password: str):
    # Authenticate user

    expires_delta = timedelta(hours=1)
    expires_at = datetime.utcnow() + expires_delta
    token = jwt.encode({
        "user_id": 123,
        "username": username,
        "exp": expires_at
    },
    JWT_SECRET,
    algorithm="HS256")

    return {"access_token": token}

在此示例中,我们在 /login/ 路径下声明了一个函数,并获取了用户名和密码。然后,我们对用户进行身份验证,并在成功验证后创建一个令牌。

我们通过使用 PyJWT 库的 jwt.encode() 方法来编码 JWT 令牌。此方法接受一个字典作为输入,带有用户 ID、用户名和过期时间等字段。过期时间将在此示例中设置为一个小时。

最后,我们将生成的令牌作为 JSON 对象返回给客户端。

总结

需要登录功能在 FastAPI 中很容易实现,并且您可以使用 OAuth2 或 JWT 来实现身份验证。不管您选择哪种方式,都需要注意以下要点:

1.明确需要登录的端点并对其进行保护。

  1. 要构建自己的身份验证 UI 或使用现有的身份验证服务。

  2. 如果使用 JWT,需要设置有效期限以及安全的密钥。