from fastapi import APIRouter, Depends, HTTPException, Request, Form, Response from fastapi.responses import RedirectResponse from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from fastapi.security import OAuth2PasswordBearer from fastapi.templating import Jinja2Templates from passlib.context import CryptContext from datetime import datetime, timedelta import jwt from model.database import get_async_session, User # from model.models import User router = APIRouter() templates = Jinja2Templates(directory="templates") SECRET_KEY = "your_secret_key" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") def create_access_token(data: dict, expires_delta: timedelta = None): to_encode = data.copy() expire = datetime.utcnow() + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)) to_encode.update({"exp": expire}) return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) async def authenticate_user(db: AsyncSession, username: str, password: str): stmt = select(User).where(User.username == username) result = await db.execute(stmt) user = result.scalar_one_or_none() if not user or not pwd_context.verify(password, user.hashed_password): return None return user @router.get("/login") async def login_page(request: Request): return templates.TemplateResponse("login.html", {"request": request}) @router.post("/login") async def login( response: Response, username: str = Form(...), password: str = Form(...), db: AsyncSession = Depends(get_async_session) ): user = await authenticate_user(db, username, password) if not user: return Response(content="Неправильный логин или пароль", media_type="text/html") access_token = create_access_token(data={"sub": username, "role": user.role}) response = RedirectResponse(url="/product", status_code=303) response.set_cookie(key="access_token", value=access_token, httponly=True) return response @router.get("/logout") async def logout(): response = RedirectResponse(url="/login", status_code=303) response.delete_cookie("access_token") return response