linkedin2/routers/logins.py

64 lines
2.3 KiB
Python

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="/", 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