From f4e46bef22650f2053fd2d666b8120ae852f15d1 Mon Sep 17 00:00:00 2001 From: IluaAir Date: Sat, 27 Sep 2025 11:24:57 +0300 Subject: [PATCH] full refresh token --- src/api/dependacies/user_dep.py | 2 +- src/api/v1/auth.py | 8 +++--- src/core/database.py | 2 +- src/core/settings.py | 1 + src/services/auth.py | 51 +++++++++++++++------------------ 5 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/api/dependacies/user_dep.py b/src/api/dependacies/user_dep.py index 731627b..31c50b4 100644 --- a/src/api/dependacies/user_dep.py +++ b/src/api/dependacies/user_dep.py @@ -37,7 +37,7 @@ async def get_current_user( user = TokenData(**payload) if check_active and not user.is_active: raise HTTPException(status_code=400, detail="Inactive user") - except InvalidTokenError: + except (InvalidTokenError, AttributeError): raise credentials_exception return user diff --git a/src/api/v1/auth.py b/src/api/v1/auth.py index d728740..e727233 100644 --- a/src/api/v1/auth.py +++ b/src/api/v1/auth.py @@ -35,8 +35,8 @@ async def login( value=result["refresh_token"], httponly=True, samesite="lax", - path=settings.api.v1.auth, - max_age=60 * 60 * 24 * settings.refresh_token.expire_days, + path=settings.api.v1_login_url, + max_age=60 * 60 * 24 * 7, ) return result @@ -46,7 +46,7 @@ async def refresh( session: sessionDep, current_user: RefreshUser, response: Response, - fingerprint: str = Body(), + fingerprint: Annotated[str, Body()], refresh_token: Annotated[str | None, Cookie(name="refresh_token")] = None, ): if refresh_token is None: @@ -57,7 +57,7 @@ async def refresh( value=result["refresh_token"], httponly=True, samesite="lax", - path=settings.api.v1.auth, + path=settings.api.v1_login_url, max_age=60 * 60 * 24 * settings.refresh_token.expire_days, ) return result diff --git a/src/core/database.py b/src/core/database.py index 98738a4..3bdc459 100644 --- a/src/core/database.py +++ b/src/core/database.py @@ -6,7 +6,7 @@ from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from src.core.settings import settings -engine = create_async_engine(settings.db.url, echo=True) +engine = create_async_engine(settings.db.url, echo=settings.db.echo) @event.listens_for(engine.sync_engine, "connect") diff --git a/src/core/settings.py b/src/core/settings.py index 5425743..824f89b 100644 --- a/src/core/settings.py +++ b/src/core/settings.py @@ -28,6 +28,7 @@ class ApiPrefix(BaseModel): class DbSettings(BaseModel): url: str = f"sqlite+aiosqlite:///{DB_PATH}" + echo: bool = False class AccessToken(BaseModel): diff --git a/src/services/auth.py b/src/services/auth.py index c03b952..572fe39 100644 --- a/src/services/auth.py +++ b/src/services/auth.py @@ -19,6 +19,20 @@ class AuthService(BaseService): await self.session.commit() return User.model_validate(result) + async def _tokens_create(self, user_data: TokenData, fingerprint: str): + access_token = AuthManager.create_access_token(user_data.model_dump()) + refresh_token = AuthManager.create_refresh_token() + await self.session.auth.create_one({ + "token": refresh_token, + "user_id": user_data.id, + "fingerprint": fingerprint + }) + return { + "access_token": access_token, + "token_type": settings.access_token.token_type, + "refresh_token": refresh_token, + } + async def login(self, username: str, password: str, fingerprint: str) -> dict: result = await self.session.user.get_one_or_none(username=username) if result is None: @@ -36,39 +50,20 @@ class AuthService(BaseService): status_code=401, detail="Incorrect username or password", ) - access_token = AuthManager.create_access_token(token_data.model_dump()) - refresh_token = AuthManager.create_refresh_token() - await self.session.auth.create_one({ - "token": refresh_token, - "user_id": user.id, - "fingerprint": fingerprint - }) - await self.session.commit() - return { - "access_token": access_token, - "token_type": settings.access_token.token_type, - "refresh_token": refresh_token, - } - - async def delete_token(self, token: str) -> None: - await self.session.auth.delete_one(token=token) + tokens = await self._tokens_create(token_data, fingerprint) await self.session.commit() + print(tokens) + return tokens async def refresh_tokens(self, refresh_token: str, user_data: TokenData, fingerprint: str) -> dict: token_record = await self.session.auth.get_one_or_none(token=refresh_token) if not token_record or token_record.user_id != user_data.id: raise HTTPException(status_code=401, detail="Invalid refresh token") - new_access_token = AuthManager.create_access_token(user_data.model_dump()) - new_refresh_token = AuthManager.create_refresh_token() + token = await self._tokens_create(user_data, fingerprint) await self.session.auth.delete_one(token=refresh_token) - await self.session.auth.create_one({ - "token": new_refresh_token, - "user_id": user_data.id, - "fingerprint": fingerprint - }) await self.session.commit() - return { - "access_token": new_access_token, - "token_type": settings.access_token.token_type, - "refresh_token": new_refresh_token, - } + return token + + async def delete_token(self, token: str) -> None: + await self.session.auth.delete_one(token=token) + await self.session.commit()