create project

This commit is contained in:
2026-07-16 16:06:22 +03:00
parent 0a81898f29
commit a8a18abf30
10 changed files with 256 additions and 8 deletions
+80
View File
@@ -0,0 +1,80 @@
from datetime import datetime, timedelta
from typing import Optional
from fastapi import Depends, HTTPException, status
from jose import jwt, JWTError
from fastapi.security import OAuth2PasswordBearer
import bcrypt
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from app.models import User
from app.schemas import Token
from app.db import get_db
import os
# Загружаем переменные окружения
SECRET_KEY = os.getenv("SECRET_KEY")
ALGORITHM = os.getenv("ALGORITHM", "HS256")
ACCESS_TOKEN_EXPIRE_MINUTES = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "60"))
# ---------------------------------------------------------
# Хэширование пароля
# ---------------------------------------------------------
def hash_password(password: str) -> str:
pwd_bytes = password.encode('utf-8')
salt = bcrypt.gensalt()
return bcrypt.hashpw(pwd_bytes, salt).decode('utf-8')
def verify_password(plain_password: str, hashed_password: str) -> bool:
return bcrypt.checkpw(
plain_password.encode('utf-8'),
hashed_password.encode('utf-8')
)
# ---------------------------------------------------------
# Создание JWT-токена
# ---------------------------------------------------------
def create_access_token(data: dict, expires_delta: Optional[int] = None):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(
minutes=expires_delta or ACCESS_TOKEN_EXPIRE_MINUTES
)
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
# ---------------------------------------------------------
# Получение текущего пользователя по токену
# ---------------------------------------------------------
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(
token: str = Depends(oauth2_scheme),
db: AsyncSession = Depends(get_db)
):
""" Достаём токен из Authorization Bearer """
if not token or not isinstance(token, str):
raise HTTPException(status_code=401, detail="Missing token")
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
email: str = payload.get("sub")
if email is None:
raise HTTPException(status_code=401, detail="Invalid token payload")
except JWTError:
raise HTTPException(status_code=401, detail="Invalid or expired token")
query = select(User).where(User.email == email)
result = await db.execute(query)
user = result.scalar_one_or_none()
if user is None:
raise HTTPException(status_code=404, detail="User not found")
return user