init
This commit is contained in:
70
src/presentation/routing/jwt.py
Normal file
70
src/presentation/routing/jwt.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi.responses import ORJSONResponse
|
||||
from starlette import status
|
||||
|
||||
from src.application.commands import AdminJwtRefreshCommand
|
||||
from src.application.domain.exceptions import ApplicationException, RefreshConcurrentException
|
||||
from src.infrastructure.config import settings
|
||||
from src.presentation.dependencies.commands import get_admin_jwt_refresh_command
|
||||
|
||||
jwt_router = APIRouter(prefix='/jwt', tags=['jwt'])
|
||||
|
||||
|
||||
def _clear_auth_cookies(response: ORJSONResponse) -> None:
|
||||
response.delete_cookie('access_token', path='/', domain=settings.ADMIN_COOKIE_DOMAIN)
|
||||
response.delete_cookie('refresh_token', path='/', domain=settings.ADMIN_COOKIE_DOMAIN)
|
||||
|
||||
|
||||
def _set_auth_cookies(response: ORJSONResponse, access: str, refresh: str) -> None:
|
||||
response.set_cookie(
|
||||
key='access_token',
|
||||
value=access,
|
||||
httponly=True,
|
||||
secure=settings.ADMIN_COOKIE_SECURE,
|
||||
samesite='lax',
|
||||
path='/',
|
||||
domain=settings.ADMIN_COOKIE_DOMAIN,
|
||||
max_age=int(settings.JWT_ACCESS_TTL_SECONDS),
|
||||
)
|
||||
response.set_cookie(
|
||||
key='refresh_token',
|
||||
value=refresh,
|
||||
httponly=True,
|
||||
secure=settings.ADMIN_COOKIE_SECURE,
|
||||
samesite='lax',
|
||||
path='/',
|
||||
domain=settings.ADMIN_COOKIE_DOMAIN,
|
||||
max_age=int(settings.JWT_REFRESH_TTL_SECONDS),
|
||||
)
|
||||
|
||||
|
||||
@jwt_router.post('/refresh', response_class=ORJSONResponse, status_code=status.HTTP_200_OK)
|
||||
async def refresh_tokens(
|
||||
request: Request,
|
||||
command: AdminJwtRefreshCommand = Depends(get_admin_jwt_refresh_command),
|
||||
):
|
||||
refresh_token = request.cookies.get('refresh_token')
|
||||
if not refresh_token:
|
||||
response = ORJSONResponse({'ok': False, 'error': 'No refresh token'}, status_code=401)
|
||||
_clear_auth_cookies(response)
|
||||
return response
|
||||
|
||||
xff = request.headers.get('x-forwarded-for')
|
||||
ip = xff.split(',')[0].strip() if xff else (request.client.host if request.client else None)
|
||||
user_agent = request.headers.get('user-agent')
|
||||
|
||||
try:
|
||||
tokens = await command(refresh_token=refresh_token, ip=ip, user_agent=user_agent)
|
||||
except RefreshConcurrentException:
|
||||
return ORJSONResponse({'result': True, 'concurrent': True}, status_code=status.HTTP_200_OK)
|
||||
except ApplicationException as exc:
|
||||
if exc.status_code == status.HTTP_401_UNAUTHORIZED:
|
||||
response = ORJSONResponse({'result': False}, status_code=401)
|
||||
_clear_auth_cookies(response)
|
||||
return response
|
||||
raise
|
||||
|
||||
access, refresh = tokens
|
||||
response = ORJSONResponse({'result': True})
|
||||
_set_auth_cookies(response, access, refresh)
|
||||
return response
|
||||
Reference in New Issue
Block a user