diff --git a/apps/api/app/api/routes/auth.py b/apps/api/app/api/routes/auth.py index 9a9d83ab3..eacf9dc94 100755 --- a/apps/api/app/api/routes/auth.py +++ b/apps/api/app/api/routes/auth.py @@ -17,6 +17,8 @@ from packages.adapters.redis import NoopSessionStore from packages.adapters.smtp import NoopEmailService from packages.application.auth.login_use_case import LoginRequest as LoginUseCaseRequest from packages.application.auth.login_use_case import LoginUseCase +from packages.application.auth.login_use_case import RefreshTokenRequest as RefreshTokenUseCaseRequest +from packages.application.auth.login_use_case import RefreshTokenUseCase from packages.application.auth.password_reset_use_case import RequestPasswordResetRequest as PasswordResetUseCaseRequest from packages.application.auth.password_reset_use_case import ( RequestPasswordResetUseCase, @@ -50,8 +52,12 @@ class LoginRequest(BaseModel): password: str +class RefreshRequest(BaseModel): + refresh_token: str + class LoginResponse(BaseModel): access_token: str + refresh_token: str token_type: str = "bearer" user_id: str email: str @@ -133,6 +139,7 @@ async def login( return LoginResponse( access_token=response.access_token, + refresh_token=response.refresh_token, user_id=response.user_id, email=response.email, username=response.username, @@ -141,6 +148,32 @@ async def login( ) +@router.post("/refresh") +async def refresh( + request: RefreshRequest, + user_repository: UserRepository = Depends(get_user_repository), + session_store=Depends(get_auth_session_store), +): + use_case = RefreshTokenUseCase( + user_repository=user_repository, + session_store=session_store, + ) + response, error = use_case.execute(RefreshTokenUseCaseRequest(refresh_token=request.refresh_token)) + if error or response is None: + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired refresh token") + + return LoginResponse( + access_token=response.access_token, + refresh_token=response.refresh_token, + user_id=response.user_id, + email=response.email, + username=response.username, + display_name=response.display_name, + expires_in=response.expires_in, + ) + + + def _verify_email_token(token: str, user_repository: UserRepository) -> MessageResponse: success, error = VerifyEmailUseCase(user_repository=user_repository).execute(VerifyEmailRequest(token=token)) if not success: diff --git a/packages/application/auth/jwt_service.py b/packages/application/auth/jwt_service.py index 082f11ad2..8b1db5930 100644 --- a/packages/application/auth/jwt_service.py +++ b/packages/application/auth/jwt_service.py @@ -14,8 +14,8 @@ class JWTConfig: self, secret_key: str, algorithm: str = "HS256", - access_token_expire_minutes: int = 30, - refresh_token_expire_days: int = 30, + access_token_expire_minutes: int = 15, + refresh_token_expire_days: int = 7, ): """ 初始化 JWT 配置