So using FastAPI PyJWT, I'm struggling to make this work
user_dep = Annotated[Dict,Depends(api.get_current_user)]
@app.get('/')
async def home(request: Request,user:user_dep=Optional[models.AuthorizedUser]):
print(user)
if user is not None:
return RedirectResponse(url='/dashboard/')
return templates.TemplateResponse('home.html',context={'request':request})
Intended functionality: If the user is already logged in, they should automatically be redirected to the intended page I want.
Running this exact piece of code and when I hit the /
path, it returns 401 Unauthorized
error, which is not what I currently want for this one.
async def get_current_user(token: Annotated[str,Depends(oauth2_bearer)]):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get('username')
user_id: int = payload.get('id')
rank: str = payload.get('rank')
division: str = payload.get('division')
if username is None or user_id is None:
return None
#raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate user")
return {'username': username, 'id': user_id, 'rank': rank, 'division':division}
except PyJWTError:
return None
#raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials")
Is there a possibility I am missing some steps, or anything?
I've tried everything, even removing doing the following, but nothing seems to work:
@app.get('/')
async def home(request: Request,user:user_dep=None):
print(user)
if user is not None:
return RedirectResponse(url='/dashboard/')
return templates.TemplateResponse('home.html',context={'request':request})
@app.get('/')
async def home(request: Request):
user = await user_dep()
print(user)
if user is not None:
return RedirectResponse(url='/dashboard/')
return templates.TemplateResponse('home.html',context={'request':request})
OAuth2PasswordBearer
will (by default) generate a 401 error when an Authorization
header is not present, so your dependency code never actually runs (so you can't return None
).
To change the behavior you can supply the parameter auto_error
when creating your OAuth2PasswordBearer
instance.
By default, if no HTTP Auhtorization header is provided, required for OAuth2 authentication, it will automatically cancel the request and send the client an error.
If
auto_error
is set toFalse
, when the HTTP Authorization header is not available, instead of erroring out, the dependency result will beNone
.This is useful when you want to have optional authentication.
It is also useful when you want to have authentication that can be provided in one of multiple optional ways (for example, with OAuth2 or in a cookie).
You then check if token
is None
before attempting to decode it in your authentication function.
However, be aware that this will also make all other endpoints available if no token is present, just without user information. A solution to this is to define two get_current_user
functions, one get_current_user
and one get_optional_user
, which in turn either can depend on two differently configured instances of OAuth2PasswordBearer
, or you can handle the None
case for the token in your get_current_user
function and raise a 401 if the token isn't present yourself.