将FastApi与Supabase Auth集成
#python #fastapi #supabase #authentication

为什么这篇文章以及我们将介绍的内容

在本文中,我们将介绍如何使用supabase auth实现登录和注销功能的基础。我们还将介绍如何进行防护路由,以便只有在用户中签名才能访问受保护的路由。

什么是supabase auth

supabase是基于JSON Web令牌的Auth Service-它占用用户的凭据(例如电子邮件和密码),并返回用于在当事方之间安全过境信息的令牌。然后,其他服务可以利用此代币以了解有关用户的更多信息。例如,我们可以确定用户的角色以及他们用来登录的身份验证方法。

创建注册路线

如果与supabase auth集成,则只需要将客户端库包装在路由中即可登录,注册和签名功能。这是一个例子:

初始化集中文件中的客户端

import os
from supabase import create_client, Client

url: str = os.environ.get("SUPABASE_URL")
key: str = os.environ.get("SUPABASE_KEY")
supa: Client = create_client(url, key)

将客户端导入您的应用程序逻辑:

from .supabase import supa

@app.get("/sign_up")
def sign_up():
  res = supa.auth.sign_up(email="testsupa@gmail.com",
                          password="testsupabasenow")
  return res.get("access_token")

@app.get("/sign_out")
def sign_out():
  supa = init_supabase()
  res = supa.auth.sign_out()
  return "success"

@app.get("/sign_in")
def sign_in():
  supa = init_supabase()
  res = supa.auth.sign_in_with_password({"email":"testsupa@gmail.com", "password": "testsupabasenow"})
  return res.get("access_token")

要保护路线,有两个主要选择:

  1. 我们可以编写中间件功能来验证传入的JWT
  2. 我们可以使用默认fastapi httpbearer的扩展版和依赖项注入来验证路线

我们将使用第二种选项,因为它的详细信息稍小。

让我们扩展内置的HTTP承载类中的内置以解码和验证JWT。我们可以通过使用python-josePyJWT之类的JWT库来做到这一点。我们还需要在编写时设置> auth的supabase JWT秘密。

JWT Bearer课

让我们扩展内置的JWT承载者 - 下面是从TestDriven.io's blog拍摄的片段,它对JWT进行验证以确保凭据有效。

class JWTBearer(HTTPBearer):
    def __init__(self, auto_error: bool = True):
        super(JWTBearer, self).__init__(auto_error=auto_error)

    async def __call__(self, request: Request):
        credentials: HTTPAuthorizationCredentials = await super(JWTBearer, self).__call__(request)
        if credentials:
            if not credentials.scheme == "Bearer":
                raise HTTPException(status_code=403, detail="Invalid authentication scheme.")
            if not self.verify_jwt(credentials.credentials):
                raise HTTPException(status_code=403, detail="Invalid token or expired token.")
            return credentials.credentials
        else:
            raise HTTPException(status_code=403, detail="Invalid authorization code.")

    def verify_jwt(self, jwtoken: str) -> bool:
        isTokenValid: bool = False

        try:
            payload = decodeJWT(jwtoken)
        except:
            payload = None
        if payload:
            isTokenValid = True
        return isTokenValid

为了保护路线,我们可以导入扩展的HTTP承载类,并使用依赖项,FastAPI中的选项来保护路线。

这就是它的样子:

from auth import JWTBearer
@app.post('/my-protected-route/',dependencies=[Depends(JWTBearer())], response_model=SchemaJob)
async def job(job: SchemaJob):
    ...
    # Some work here

瞧,您有一个受保护的路线。在此保护的情况下,如果不包含Authorization Bearer: <jwt-token>标头,请要求保护路线。

也可以通过基于上述JWTBearer类的def __call__中的索赔或角色实现自定义检查来扩展此实现。有关JWTS的更多信息,您可能希望查看Supabase website Auth section,以更深入地了解JWTS的功能。

这是sample repo。请随时在下面的评论中留下任何问题。

示例代码从:

中绘制参考
  1. https://testdriven.io/blog/fastapi-jwt-auth/
  2. https://educative.io/answers/how-to-use-postgresql-database-in-fastapi