add login endpoint

This commit is contained in:
IluaAir
2025-09-21 12:08:04 +03:00
parent 8620e9b5a1
commit cd51902313
8 changed files with 41 additions and 21 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,7 +1,6 @@
import os
import secrets
from datetime import datetime, timedelta, timezone
import bcrypt
import jwt
from passlib.context import CryptContext
@@ -38,9 +37,10 @@ class AuthManager:
@classmethod
def create_refresh_token(cls) -> str:
random_bytes = os.urandom(32)
data = b'settings.refresh_token.secret_key' + random_bytes
token_hash = bcrypt.hashpw(data, bcrypt.gensalt(rounds=12)).decode()
# 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

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": ...

View File

@@ -40,18 +40,10 @@ class AccessToken(BaseSettings):
token_type: str = "bearer" # noqa: S105
class RefreshToken(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env", env_file_encoding="utf-8", env_prefix="REFRESH_TOKEN_"
)
secret_key: str
class Settings(BaseSettings):
api: ApiPrefix = ApiPrefix()
db: DbSettings = DbSettings()
access_token: AccessToken = AccessToken() # type: ignore
refresh_token: RefreshToken = RefreshToken() # type: ignore
settings = Settings()

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}