feat: Update JWT refresh token endpoint to include user manager dependency
This commit enhances the JWT refresh token functionality by introducing a user manager dependency for loading user instances from the database. It also adds detailed documentation for the refresh token process, ensuring clarity on the expected request format and error handling for invalid tokens. These changes aim to improve security and maintainability of the authentication flow.
This commit is contained in:
parent
0207c175ba
commit
1897d48188
@ -4,7 +4,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from app.database import get_transactional_session
|
||||
from app.models import User
|
||||
from app.auth import oauth, fastapi_users, auth_backend, get_jwt_strategy, get_refresh_jwt_strategy
|
||||
from app.auth import oauth, fastapi_users, auth_backend, get_jwt_strategy, get_refresh_jwt_strategy, get_user_manager
|
||||
from app.config import settings
|
||||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
|
||||
@ -88,16 +88,33 @@ async def apple_callback(request: Request, db: AsyncSession = Depends(get_transa
|
||||
return RedirectResponse(url=redirect_url)
|
||||
|
||||
@router.post('/jwt/refresh')
|
||||
async def refresh_jwt_token(request: Request):
|
||||
async def refresh_jwt_token(
|
||||
request: Request,
|
||||
user_manager=Depends(get_user_manager),
|
||||
):
|
||||
"""Refresh the JWT access token using a valid refresh token.
|
||||
|
||||
The incoming request must provide a JSON body with a ``refresh_token`` field.
|
||||
A new access and refresh token pair will be returned when the provided refresh
|
||||
token is valid. If the token is invalid or expired, a *401* error is raised.
|
||||
"""
|
||||
|
||||
data = await request.json()
|
||||
refresh_token = data.get('refresh_token')
|
||||
|
||||
if not refresh_token:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Missing refresh token")
|
||||
|
||||
refresh_strategy = get_refresh_jwt_strategy()
|
||||
|
||||
try:
|
||||
user = await refresh_strategy.read_token(refresh_token, None)
|
||||
# ``read_token`` needs a callback capable of loading the *User* from the
|
||||
# database. We therefore pass the user manager obtained via dependency
|
||||
# injection so that the strategy can hydrate the full *User* instance.
|
||||
user = await refresh_strategy.read_token(refresh_token, user_manager)
|
||||
except Exception:
|
||||
# Any error during decoding or lookup should result in an unauthorized
|
||||
# response to avoid leaking information about token validity.
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid refresh token")
|
||||
|
||||
if not user:
|
||||
@ -106,6 +123,7 @@ async def refresh_jwt_token(request: Request):
|
||||
access_strategy = get_jwt_strategy()
|
||||
access_token = await access_strategy.write_token(user)
|
||||
new_refresh_token = await refresh_strategy.write_token(user)
|
||||
|
||||
return JSONResponse({
|
||||
"access_token": access_token,
|
||||
"refresh_token": new_refresh_token,
|
||||
|
Loading…
Reference in New Issue
Block a user