Reputation: 1137
what is the best way to provide an authentication for API. I read about authentication, Given an approach to write user: str = Depends(get_current_user) for each every function. I don't think so this is the good way to write an authentication. Can we erite a middleware for it, and add a userid to request object, so that we can take that in the API request processing. Could you any send me the middleware if some one already written.
Upvotes: 10
Views: 19975
Reputation: 11357
I had the same problem. I wanted to check Basic Authentication using middleware.
Here is a simple solution
from fastapi import Request, FastAPI
from fastapi.responses import JSONResponse
import base64
app = FastAPI()
def check_permission(method, api, auth):
# The following paths are always allowed:
if method == 'GET' and api[1:] in ['docs', 'openapi.json', 'favicon.ico']:
return True
# Parse auth header and check scheme, username and password
scheme, data = (auth or ' ').split(' ', 1)
if scheme != 'Basic':
return False
username, password = base64.b64decode(data).decode().split(':', 1)
if username=='john' and password=='test123':
return True
@app.middleware("http")
async def check_authentication(request: Request, call_next):
auth = request.headers.get('Authorization')
if not check_permission(request.method, request.url.path, auth):
return JSONResponse(None, 401, {"WWW-Authenticate": "Basic"})
return await call_next(request)
@app.get("/test")
async def root():
return {"message": "Hello World"}
When the user tries to access /test
it will fail with 401 unless the correct credentials are supplied. This works ok in Swagger also. You don't get the padlock icon, but you do get the login pop-up (assuming Chrome is configured correctly).
Upvotes: 4