This commit is contained in:
Андрей Дувакин 2024-10-04 19:26:11 +05:00
parent 48ddeb84c2
commit 87f69be548
3 changed files with 72 additions and 2 deletions

View File

@ -0,0 +1,50 @@
from datetime import datetime, timedelta, timezone
from typing import Optional
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
import jwt
from sqlalchemy.orm import Session
from dotenv import load_dotenv
import os
from app.infrastructure.database.dependencies import get_db
from app.infrastructure.database.repository.user_repository import UsersRepository
load_dotenv()
SECRET_KEY = os.getenv("SECRET_KEY")
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.now(timezone.utc) + expires_delta
else:
expire = datetime.now(timezone.utc) + timedelta(minutes=15)
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
def verify_token(token: str, db: Session = Depends(get_db)):
credentials_exception = HTTPException(
status_code=401,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id: str = payload.get("sub")
if user_id is None:
raise credentials_exception
user_repo = UsersRepository(db)
user = user_repo.get_by_id(
int(user_id)
)
if user is None:
raise credentials_exception
return user
except jwt.PyJWTError: # Обрабатываем исключения от PyJWT
raise credentials_exception

View File

@ -12,6 +12,9 @@ class UsersRepository:
def get_by_id(self, user_id: int):
return self.db.query(User).filter(User.id == user_id).first()
def get_by_login(self, user_login: str):
return self.db.query(User).filter(User.login == user_login).first()
def create(self, user: User):
self.db.add(user)
self.db.commit()

View File

@ -1,11 +1,15 @@
from typing import List
from fastapi import APIRouter, HTTPException, Depends
from fastapi import APIRouter, Depends
from fastapi import HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from app.infrastructure.database.dependencies import get_db
from app.core.entities.user import UserEntity
from app.core.usecases.auth_service import create_access_token
from app.core.usecases.user_service import UsersService
from app.infrastructure.database.dependencies import get_db
from app.infrastructure.database.repository.user_repository import UsersRepository
router = APIRouter()
@ -47,3 +51,16 @@ def delete_user(user_id: int, db: Session = Depends(get_db)):
if not success:
raise HTTPException(status_code=404, detail="User not found")
return success
@router.post("/token")
def login(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
user_repo = UsersRepository(db)
user = user_repo.get_by_login(
form_data.username
)
if not user or user.password != form_data.password:
raise HTTPException(status_code=400, detail="Incorrect username or password")
access_token = create_access_token(data={"sub": user.id})
return {"access_token": access_token, "token_type": "bearer"}