简体   繁体   English

覆盖 FastAPI 中某些端点的全局依赖关系

[英]Override global dependency for certain endpoints in FastAPI

I have a FastAPI server that communicates with a web app.我有一个与 web 应用程序通信的 FastAPI 服务器。 My web app also has 2 types of users, Users (non-admins) and Admins.我的 web 应用程序也有两种类型的用户,用户(非管理员)和管理员。 I added a global dependency to FastAPI to verify the user.我向 FastAPI 添加了一个全局依赖项来验证用户。 I want the verify dependency to only allow Admins to access endpoints by default, and have some decorator (or something similar) to allow non-admins to access certain routes.我希望验证依赖项默认情况下只允许管理员访问端点,并有一些装饰器(或类似的东西)来允许非管理员访问某些路由。 This way, no one accidentally creates a public route that is supposed to be only for admins.这样,没有人会意外地创建一个应该仅供管理员使用的公共路由。


    def verify_token(request: Request):
      # make sure the user's auth token is valid
      # retrieve the user's details from the database
      # make sure user is Admin, otherwise throw HTTP exception
      return True
      
    app = FastAPI(
            title="My App",
            dependencies=[Depends(verify_token)]
          )
          
    @app.get(/admins_only)
    def admins_only():
      # this works well!
      return {'result': 2}
      
    @app.get(/non_admin_route)
    def non_admin_route():
      # this doesn't work because verify_token
      # only allows admins by default, but it should
      # be accessible to non admins
      return {'result': 1}

You cannot have conditional global dependencies.你不能有条件的全局依赖。 You either have them on all endpoints of your app, or on none of them.您要么在应用程序的所有端点上安装它们,要么在任何一个端点上都没有。 My recommendation is to split your endpoints in two routers, and only add routes to the respective routers.我的建议是将您的端点分成两个路由器,并且只添加到各自路由器的路由。 Then you can add a global dependency to only one of the routers like this:然后,您可以像这样仅向其中一个路由器添加全局依赖项:

from fastapi import APIRouter, FastAPI, Request, Depends

def verify_token(request: Request):
      # make sure the user's auth token is valid
      # retrieve the user's details from the database
      # make sure user is Admin, otherwise throw HTTP exception
      return True
      
app = FastAPI(
        title="My App",
        )
        
only_admin_router = APIRouter(
    tags=["forAdmins"],
    dependencies=[Depends(verify_token)]
)

all_users_router = APIRouter(tags="forEverybody")

@only_admin_router.get("/admins_only")
def admins_only():
    # this will only work if verify doesn't raise.
    return {'result': 2}
    
@all_users_router.get("/non_admin_route")
def non_admin_route():
    #this will work for all users, verify will not be called.
    return {'result': 1}

app.include_router(only_admin_router)
app.include_router(all_users_router)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM