/
DATKAI
/
click_vpn
Обзор
Документация
Войти
/
DATKAI
/
click_vpn
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/auth.py
59 строк
2 KB
VPN Manager
fix: replace passlib with bcrypt directly — fixes bcrypt 4.x compatibility
01 июн 2026, 13:49
01 июн 2026, 13:49
a31ec37
Код
Авторство
О чём код?
import os from datetime import datetime, timedelta from typing import Optional import bcrypt from jose import JWTError, jwt from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer from sqlalchemy.orm import Session from database import get_db from models import AdminUser SECRET_KEY = os.getenv("SECRET_KEY", "change-me-in-production-use-strong-random-key") ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = int(os.getenv("TOKEN_EXPIRE_MINUTES", "480")) # 8 часов oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/auth/login") def hash_password(password: str) -> str: # bcrypt ограничен 72 байтами — обрезаем pwd_bytes = password.encode("utf-8")[:72] return bcrypt.hashpw(pwd_bytes, bcrypt.gensalt()).decode("utf-8") def verify_password(plain: str, hashed: str) -> bool: pwd_bytes = plain.encode("utf-8")[:72] return bcrypt.checkpw(pwd_bytes, hashed.encode("utf-8")) def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str: to_encode = data.copy() expire = datetime.utcnow() + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)) to_encode["exp"] = expire return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) def get_current_user( token: str = Depends(oauth2_scheme), db: Session = Depends(get_db), ) -> AdminUser: credentials_exc = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Неверные учётные данные", headers={"WWW-Authenticate": "Bearer"}, ) try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) username: str = payload.get("sub") if username is None: raise credentials_exc except JWTError: raise credentials_exc user = db.query(AdminUser).filter(AdminUser.username == username).first() if user is None or not user.is_active: raise credentials_exc return user