问题:
FastAPI中利用Dependency Inject的方式,可以在方法被调用之前做条件检查。当然Dependency Inject可以做的事情很多,比如只初始化一次调用训练好的AI模型。
排除登录接口,避免检查Token。可以用API编排的方式,不设置Dependency。也可以通过继承OAuth2PasswordBearer这个callable类来改写其中__Call__方法的逻辑。
方案:
1、简单编程:利用APIRouter(dependencies= ) 或 include_router(dependencies= ) 中设置,建议使用后者在统一的地方进行处理。
2、继承改写:继承OAuth2PasswordBearer类,改写其中的验证逻辑。
Talk is cheap, Show code.
代码:
方案1:把不需要验证Token的接口安排在同一个APIRouter中
check_token = OAuth2PasswordBearer("/login")
app = FastAPI()
app.include_router(loginAPI, tags=["Login"])
app.include_router(userAPI, prefix="/user", tags=["User"], dependencies=[Depends(check_token)])
app.include_router(prodAPI, prefix="/prod", tags=["Prod"], dependencies=[Depends(check_token)])
......
方案2:继承改写OAuth2PasswordBearer类,无须考虑Path
class SecurityIgnorePathEnum(str, Enum):
login = "/user/login"
apilogin="/user/apilogin"
docs = "/docs"
openapi = "/openapi.json"
class VerifyTokenMiddleware(OAuth2PasswordBearer):
def __init__(self, tokenUrl):
super().__init__(
tokenUrl= tokenUrl,
auto_error= True
)
async def __call__(self, request: Request) -> str | None:
path:str = request.get("path")
if path.startswith(tuple(member.value for member in SecurityIgnorePathEnum)):
return None
authorization:str = request.headers.get("Authorization")
scheme,playload = get_authorization_scheme_param(authorization)
if not authorization or scheme.lower() != "bearer":
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},)
return playload
全局引入依赖注入
check_token = VerifyTokenMiddleware("/user/login")
app = FastAPI(dependencies=[Depends(check_token)])
app.include_router(userAPI, prefix="/user", tags=["User"])
app.include_router(prodAPI, prefix="/prod", tags=["Prod"])