feat: Implement JWT refresh token endpoint and update OAuth routing
This commit is contained in:
parent
3ec2ff1f89
commit
dccd7bb300
@ -1,11 +1,12 @@
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi.responses import RedirectResponse
|
||||
from fastapi import APIRouter, Depends, Request, HTTPException, status
|
||||
from fastapi.responses import RedirectResponse, JSONResponse
|
||||
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.config import settings
|
||||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@ -92,4 +93,30 @@ async def apple_callback(request: Request, db: AsyncSession = Depends(get_transa
|
||||
# Redirect to frontend with tokens
|
||||
redirect_url = f"{settings.FRONTEND_URL}/auth/callback?access_token={access_token}&refresh_token={refresh_token}"
|
||||
|
||||
return RedirectResponse(url=redirect_url)
|
||||
return RedirectResponse(url=redirect_url)
|
||||
|
||||
@router.post('/jwt/refresh')
|
||||
async def refresh_jwt_token(request: Request):
|
||||
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)
|
||||
except Exception:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid refresh token")
|
||||
|
||||
if not user:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid refresh token")
|
||||
|
||||
access_strategy = get_jwt_strategy()
|
||||
access_token = await access_strategy.write_token(user)
|
||||
# Optionally, issue a new refresh token (rotation)
|
||||
new_refresh_token = await refresh_strategy.write_token(user)
|
||||
return JSONResponse({
|
||||
"access_token": access_token,
|
||||
"refresh_token": new_refresh_token,
|
||||
"token_type": "bearer"
|
||||
})
|
@ -9,6 +9,7 @@ from app.api.v1.endpoints import ocr
|
||||
from app.api.v1.endpoints import costs
|
||||
from app.api.v1.endpoints import financials
|
||||
from app.api.v1.endpoints import chores
|
||||
from app.api.auth import oauth
|
||||
|
||||
api_router_v1 = APIRouter()
|
||||
|
||||
@ -21,5 +22,6 @@ api_router_v1.include_router(ocr.router, prefix="/ocr", tags=["OCR"])
|
||||
api_router_v1.include_router(costs.router, prefix="/costs", tags=["Costs"])
|
||||
api_router_v1.include_router(financials.router, prefix="/financials", tags=["Financials"])
|
||||
api_router_v1.include_router(chores.router, prefix="/chores", tags=["Chores"])
|
||||
api_router_v1.include_router(oauth.router, prefix="/auth", tags=["Auth"])
|
||||
# Add other v1 endpoint routers here later
|
||||
# e.g., api_router_v1.include_router(users.router, prefix="/users", tags=["Users"])
|
8
fe/package-lock.json
generated
8
fe/package-lock.json
generated
@ -34,6 +34,7 @@
|
||||
"@types/date-fns": "^2.5.3",
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"@types/node": "^22.15.17",
|
||||
"@types/qs": "^6.14.0",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"@vitest/eslint-plugin": "^1.1.39",
|
||||
"@vue/eslint-config-prettier": "^10.2.0",
|
||||
@ -4291,6 +4292,13 @@
|
||||
"integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
|
||||
"integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz",
|
||||
|
@ -45,6 +45,7 @@
|
||||
"@types/date-fns": "^2.5.3",
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"@types/node": "^22.15.17",
|
||||
"@types/qs": "^6.14.0",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"@vitest/eslint-plugin": "^1.1.39",
|
||||
"@vue/eslint-config-prettier": "^10.2.0",
|
||||
|
@ -58,10 +58,10 @@ api.interceptors.response.use(
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
// Send refresh token in Authorization header as expected by backend
|
||||
const response = await api.post(API_ENDPOINTS.AUTH.REFRESH, {}, {
|
||||
// Send refresh token in request body as expected by backend
|
||||
const response = await api.post(API_ENDPOINTS.AUTH.REFRESH, { refresh_token: refreshTokenValue }, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${refreshTokenValue}`
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user