how to make fastapi use x-gitlab-token header for authentication

Viewed 367

I used this documentation to secure some endpoints in my fastapi app. It seemed to be working fine, and I was also able to run some tests (using pytest):

...
client = TestClient(app=app)
response = client.post(
            "/my_end_point",
            json={'data':'model'},
            headers={"Authorization": f"Bearer {token}"},
        )
...

My problem is, I want to connect my app to a Gitlab Webhook, and when doing that, Gitlab sends this header:

{'x-gitlab-token':'some-token-that-can-be-defined-when-setting-up-the-webhook'}

That means, even if I configure a valid token in the Gitlab Webhook configuration, it is not accepted by my FastAPI app, which returns 401 Not authorized error.

I guess my question is how to instruct FastApi to take the token from 'x-gitlab-token' key and not from 'Authorization' key

1 Answers

There's an example of how you can use Header in a dependency function in FastAPI's user guide.

A self-contained example:

import uvicorn

from fastapi import (
    Depends,
    FastAPI,
    Header,
    HTTPException,
)

def authenticate_gitlab(x_gitlab_token: str = Header(...)):
    if x_gitlab_token != 'magic':
        raise HTTPException(status_code=403)

    return x_gitlab_token

app = FastAPI()

@app.get("/")
async def req(authenticated_with: str = Depends(authenticate_gitlab)):
    return {'authenticated_with': authenticated_with}

    
if __name__ == "__main__":
    uvicorn.run("foo:app", host="127.0.0.1", port=5000, log_level="info")

This accepts any request with X-Gitlab-Token set to magic, while refusing other keys:

λ curl http://localhost:5000 -H "X-GitLab-Token: foo"
{"detail":"Forbidden"}

λ curl http://localhost:5000 -H "X-GitLab-Token: magic"
{"authenticated_with":"magic"}

You can use the dependencies argument when creating an APIRouter to have the dependency run before every route in a given router (which you can composition together as you need from multiple routers):

authenticated_router = APIRouter(dependencies=[Depends(authenticate_gitlab)])
Related