So using fastapi PyJWT which works well, I'm struggling to making 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 was already logged it, they will automatically get redirected to the intended page I want
Running this exact piece of code and when I guess the /
path, it returns 401 Unauthorized which is not what I currently what 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 sometimes, removing doing this:
`=
@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})```
```py
@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})
Nothing seems to work
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.