feat(auth): Implement /refresh endpoint and update login/register

This commit is contained in:
Yunxiao Xu
2026-02-18 13:37:16 -08:00
parent 78265c399a
commit d11f3dd00c
2 changed files with 112 additions and 5 deletions

View File

@@ -59,7 +59,8 @@ async def register(user_in: UserCreate, response: Response):
)
access_token = create_access_token(data={"sub": str(user.id)})
set_auth_cookie(response, access_token)
refresh_token = create_refresh_token(data={"sub": str(user.id)})
set_auth_cookie(response, access_token, refresh_token)
return {
"id": str(user.id),
@@ -80,15 +81,64 @@ async def login(response: Response, form_data: OAuth2PasswordRequestForm = Depen
)
access_token = create_access_token(data={"sub": str(user.id)})
set_auth_cookie(response, access_token)
refresh_token = create_refresh_token(data={"sub": str(user.id)})
set_auth_cookie(response, access_token, refresh_token)
return {"access_token": access_token, "token_type": "bearer"}
@router.post("/logout")
async def logout(response: Response):
"""Logout by clearing the auth cookie."""
response.delete_cookie(key="access_token")
"""Logout by clearing the auth cookies."""
clear_auth_cookies(response)
return {"detail": "Successfully logged out"}
@router.post("/refresh", response_model=Token)
async def refresh(request: Request, response: Response):
"""Refresh the access token using a valid refresh token."""
refresh_token = request.cookies.get("refresh_token")
if not refresh_token:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Refresh token missing"
)
from ea_chatbot.api.utils import decode_access_token # Using decode_access_token for both
payload = decode_access_token(refresh_token)
if not payload:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid refresh token"
)
if payload.get("type") != "refresh":
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token type"
)
user_id = payload.get("sub")
if not user_id:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token payload"
)
# Check if user still exists
user = history_manager.get_user_by_id(user_id)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="User not found"
)
# Issue new tokens (Rotation)
new_access_token = create_access_token(data={"sub": str(user.id)})
new_refresh_token = create_refresh_token(data={"sub": str(user.id)})
set_auth_cookie(response, new_access_token, new_refresh_token)
return {"access_token": new_access_token, "token_type": "bearer"}
@router.get("/oidc/login")
async def oidc_login(response: Response):
"""Get the OIDC authorization URL and set temporary session cookie."""
@@ -158,9 +208,10 @@ async def oidc_callback(request: Request, response: Response, code: str, state:
# 4. Sync user and establish session
user = history_manager.sync_user_from_oidc(email=email, display_name=name)
access_token = create_access_token(data={"sub": str(user.id)})
refresh_token = create_refresh_token(data={"sub": str(user.id)})
redirect_response = RedirectResponse(url=settings.frontend_url, status_code=status.HTTP_302_FOUND)
set_auth_cookie(redirect_response, access_token)
set_auth_cookie(redirect_response, access_token, refresh_token)
redirect_response.delete_cookie("oidc_session") # Cleanup
return redirect_response