Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom authentication for FastAPI

Tags:

python

fastapi

How can I create custom authentication for fastapi?

Example: I would like to make request with headers {'password': 'best password'} and if password key in header is "best password" allow to visible "auth only" content without changing it in all views (and compatible with generic documentation).

like image 594
LUshosiu Avatar asked Sep 30 '20 22:09

LUshosiu


People also ask

Is FastAPI safe?

You've seen some of the key features of FastAPI in action, including dependency injection, the OpenAPI documentation, type hinting, and OAuth implementation. FastAPI is a great option for building secure and performant backend systems.

What is OAuth2PasswordBearer?

OAuth2PasswordBearer is a dependency for the oauth2.0 authorisation, when you pass the token url: oauth2_scheme = OAuth2PasswordBearer(tokenUrl='login') login route will return a JSON response like: {"access_token": access_token, "token_type":"bearer"}


1 Answers

If you do not care about having a fancy integration with the swagger front end, you can simply create a dependency for verifying the token.

    from fastapi import FastAPI, HTTPException, Depends, Request

    def verify_token(req: Request):
        token = req.headers["Authorization"]
        # Here your code for verifying the token or whatever you use
        if token is not valid:
            raise HTTPException(
                status_code=401,
                detail="Unauthorized"
            )
        return True
    
    @app.post("/auth")
    async def login(password: str):
        if password == "my_password":
            return {"token": password} # Generate your own token
    
    @app.get("/")
    async def home(authorized: bool = Depends(verify_token)):
         if authorized:
            return {"detail": "Welcome home"}

I did not test the code, but it should be enough to give you an idea of how it should work.

If you care about having everything nicely integrated with the swagger UI, let me know. Since it's quite long and time consuming to prepare it, I won't prepare it if not necessary. Also, you'll have to follow the implementation of swagger, which, as far as I can understand from your question, not exactly what you asked for.

EDIT

Since the requests in the comments, I'll try to explain below how to achieve the integration with swagger.

The idea is to directly access the request during the login and perform some checks in order to decide whether the request is coming from swagger/openapi or from a personalized request. Then, once the parameters are obtained, perform the authentication as usual.

The code for logging in is the following. Note that it has to be adjusted based on the exact location and name of your parameters (since other people asked, I've shared a more general approach).

@app.post("/token")
async def login(req: Request, form_data: OAuth2PasswordRequestForm = Depends()):

    # Get header's data from the raw request
    # or from the swagger login form
    user = form_data.username
    print(user)
    print(req.headers["password"])

    return {"access_token": user, "token_type": "bearer"}
like image 124
lsabi Avatar answered Oct 03 '22 10:10

lsabi