Compare commits

..

2 Commits

Author SHA1 Message Date
IluaAir
cd51902313 add login endpoint 2025-09-21 12:08:04 +03:00
IluaAir
8620e9b5a1 add creation refresh token 2025-09-20 21:54:56 +03:00
7 changed files with 45 additions and 8 deletions

View File

@@ -1,10 +1,12 @@
from typing import Annotated
from fastapi import APIRouter, Depends
from fastapi import APIRouter, Depends, Response
from fastapi.security import OAuth2PasswordRequestForm
from src.api.dependacies.db_dep import sessionDep
from src.api.dependacies.user_dep import ActiveUser
from src.core.settings import settings
from src.schemas.auth import Token
from src.schemas.users import UserRequestADD
from src.services.auth import AuthService
@@ -17,12 +19,26 @@ async def registration(session: sessionDep, credential: UserRequestADD):
return auth
@router.post(path="/login")
@router.post(path="/login", response_model=Token)
async def login(
session: sessionDep,
credential: Annotated[OAuth2PasswordRequestForm, Depends()],
response: Response
):
access_token = await AuthService(session).login(
result = await AuthService(session).login(
credential.username, credential.password
)
return access_token
response.set_cookie(
key="refresh_token",
value=result["refresh_token"],
httponly=True,
samesite='lax',
path=settings.api.v1.auth,
max_age=60 * 60 * 24 * 7
)
return result
@router.post(path="/refresh")
async def refresh(user: ActiveUser, response: Response):
print(response)

View File

@@ -1,3 +1,4 @@
import secrets
from datetime import datetime, timedelta, timezone
import jwt
@@ -34,6 +35,14 @@ class AuthManager:
)
return encoded_jwt
@classmethod
def create_refresh_token(cls) -> str:
# random_bytes = os.urandom(32)
# data = settings.refresh_token.secret_key.encode() + random_bytes
# token_hash = bcrypt.hashpw(data, bcrypt.gensalt(rounds=12)).decode()
token_hash = secrets.token_urlsafe(32)
return token_hash
@classmethod
def decode_access_token(cls, token: str) -> dict:
return jwt.decode(

View File

@@ -2,6 +2,7 @@ from typing import Any
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from src.repository.auth import AuthRepo
from src.repository.tasks import TasksRepo
from src.repository.users import UsersRepo
@@ -14,6 +15,7 @@ class DBManager:
self.session: AsyncSession = self.session_factory()
self.user = UsersRepo(self.session)
self.task = TasksRepo(self.session)
self.auth = AuthRepo(self.session)
return self
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:

View File

@@ -3,6 +3,7 @@ from typing import TYPE_CHECKING, Any, Protocol
from sqlalchemy.ext.asyncio import AsyncSession
if TYPE_CHECKING:
from src.repository.auth import AuthRepo
from src.repository.tasks import TasksRepo
from src.repository.users import UsersRepo
@@ -15,6 +16,7 @@ class IUOWDB(Protocol):
session: AsyncSession
user: 'UsersRepo'
task: 'TasksRepo'
auth: 'AuthRepo'
async def __aenter__(self) -> "IUOWDB": ...

6
src/repository/auth.py Normal file
View File

@@ -0,0 +1,6 @@
from src.models.tokens import RefreshTokensORM
from src.repository.base import BaseRepo
class AuthRepo(BaseRepo):
model: type[RefreshTokensORM] = RefreshTokensORM

View File

@@ -4,6 +4,7 @@ from pydantic import BaseModel, ConfigDict, Field
class Token(BaseModel):
access_token: str
token_type: str
model_config = ConfigDict(extra='ignore')
class TokenData(BaseModel):

View File

@@ -2,7 +2,7 @@ from fastapi import HTTPException
from src.core.auth_manager import AuthManager
from src.core.settings import settings
from src.schemas.auth import Token, TokenData
from src.schemas.auth import TokenData
from src.schemas.users import User, UserAdd, UserRequestADD, UserWithHashedPass
from src.services.base import BaseService
@@ -39,6 +39,7 @@ class AuthService(BaseService):
access_token = AuthManager.create_access_token(
user_token.model_dump()
)
return Token(
access_token=access_token, token_type=settings.access_token.token_type
)
refresh_token = AuthManager.create_refresh_token()
await self.session.auth.create_one({"token": refresh_token, "user_id": user.id})
await self.session.commit()
return {"access_token": access_token, "token_type": settings.access_token.token_type, "refresh_token": refresh_token}