@@ -9,5 +9,5 @@ python-dotenv
|
|||||||
pika
|
pika
|
||||||
Pillow
|
Pillow
|
||||||
PyJWT
|
PyJWT
|
||||||
passlib[bcrypt]
|
passlib[argon2]
|
||||||
python-multipart
|
python-multipart
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
import jwt
|
import jwt
|
||||||
import hashlib
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from passlib.context import CryptContext
|
from passlib.context import CryptContext
|
||||||
from typing import Optional, Dict
|
from typing import Optional, Dict
|
||||||
from core.config import ConfSettings
|
from core.config import ConfSettings
|
||||||
|
|
||||||
# Configurar contexto para hashing de contraseñas
|
# Configurar contexto para hashing de contraseñas
|
||||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
# Soporta argon2 (nuevo) y bcrypt (antiguo) para compatibilidad hacia atrás
|
||||||
|
pwd_context = CryptContext(
|
||||||
|
schemes=["argon2"],
|
||||||
|
deprecated=["bcrypt"],
|
||||||
|
argon2__rounds=3
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AuthService:
|
class AuthService:
|
||||||
@@ -17,32 +21,17 @@ class AuthService:
|
|||||||
self.algorithm = ConfSettings.jwt_algorithm
|
self.algorithm = ConfSettings.jwt_algorithm
|
||||||
self.expiration_hours = ConfSettings.jwt_expiration_hours
|
self.expiration_hours = ConfSettings.jwt_expiration_hours
|
||||||
|
|
||||||
def _hash_password_sha256(self, password: str) -> str:
|
|
||||||
"""
|
|
||||||
Hashea una contraseña con SHA256 para reducir su tamaño
|
|
||||||
|
|
||||||
Args:
|
|
||||||
password: Contraseña en texto plano
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Hash SHA256 en hexadecimal (64 caracteres, siempre < 72 bytes)
|
|
||||||
"""
|
|
||||||
return hashlib.sha256(password.encode()).hexdigest()
|
|
||||||
|
|
||||||
def hash_password(self, password: str) -> str:
|
def hash_password(self, password: str) -> str:
|
||||||
"""
|
"""
|
||||||
Hashea una contraseña usando SHA256 + bcrypt
|
Hashea una contraseña usando argon2
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
password: Contraseña en texto plano
|
password: Contraseña en texto plano
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Hash bcrypt de la contraseña (SHA256 + bcrypt)
|
Hash argon2 de la contraseña
|
||||||
"""
|
"""
|
||||||
# Primero hash SHA256 (64 chars hex, nunca > 72 bytes)
|
return pwd_context.hash(password)
|
||||||
# Luego bcrypt para mayor seguridad
|
|
||||||
sha256_hash = self._hash_password_sha256(password)
|
|
||||||
return pwd_context.hash(sha256_hash)
|
|
||||||
|
|
||||||
def verify_password(self, plain_password: str, hashed_password: str) -> bool:
|
def verify_password(self, plain_password: str, hashed_password: str) -> bool:
|
||||||
"""
|
"""
|
||||||
@@ -50,14 +39,12 @@ class AuthService:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
plain_password: Contraseña en texto plano
|
plain_password: Contraseña en texto plano
|
||||||
hashed_password: Hash bcrypt para verificar
|
hashed_password: Hash argon2 para verificar
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True si la contraseña es correcta, False en caso contrario
|
True si la contraseña es correcta, False en caso contrario
|
||||||
"""
|
"""
|
||||||
# Aplicar mismo proceso: SHA256 primero, luego verificar con bcrypt
|
return pwd_context.verify(plain_password, hashed_password)
|
||||||
sha256_hash = self._hash_password_sha256(plain_password)
|
|
||||||
return pwd_context.verify(sha256_hash, hashed_password)
|
|
||||||
|
|
||||||
def create_access_token(self, user_id: int, email: str) -> str:
|
def create_access_token(self, user_id: int, email: str) -> str:
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user