Update files

This commit is contained in:
glpshchn 2025-12-15 04:01:39 +03:00
parent 94798f4d8b
commit 354d9aaedd
3 changed files with 100 additions and 10 deletions

View File

@ -202,15 +202,48 @@ async def register(request: RegisterRequest, response: Response):
detail="Аккаунт уже зарегистрирован. Используйте вход по паролю." detail="Аккаунт уже зарегистрирован. Используйте вход по паролю."
) )
# Check password strength # Check password strength and length
if len(request.password) < 6: password_len = len(request.password)
print(f"[ModerationAuth] 🔍 Проверка пароля:")
print(f"[ModerationAuth] Длина в символах: {password_len}")
print(f"[ModerationAuth] Пароль (repr): {repr(request.password)}")
print(f"[ModerationAuth] Пароль (raw): {request.password}")
if password_len < 8:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Пароль должен содержать минимум 6 символов" detail="Пароль должен содержать минимум 8 символов"
) )
if password_len > 24:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Пароль должен содержать максимум 24 символа"
)
# Check password length in bytes (bcrypt limit is 72 bytes)
# Some special characters may take more than 1 byte in UTF-8 (например, эмодзи, кириллица)
password_bytes = request.password.encode('utf-8')
password_bytes_len = len(password_bytes)
print(f"[ModerationAuth] Длина в байтах (UTF-8): {password_bytes_len}")
print(f"[ModerationAuth] Байты (hex): {password_bytes.hex()}")
# Убрали проверку на 72 байта - пусть hash_password() сам обрежет
# Это позволит избежать ошибок для нормальных паролей
if password_bytes_len > 72:
print(f"[ModerationAuth] ⚠️ Пароль превышает 72 байта ({password_bytes_len} байт), будет обрезан при хешировании")
# Hash password # Hash password
try:
password_hash = hash_password(request.password) password_hash = hash_password(request.password)
except Exception as hash_error:
print(f"[ModerationAuth] ❌ Ошибка при хешировании пароля: {type(hash_error).__name__}: {hash_error}")
import traceback
traceback.print_exc()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Ошибка при создании пароля: {str(hash_error)}"
)
# Update user # Update user
await users_collection().update_one( await users_collection().update_one(

View File

@ -19,12 +19,64 @@ security = HTTPBearer(auto_error=False)
def hash_password(password: str) -> str: def hash_password(password: str) -> str:
"""Hash password with bcrypt""" """
return pwd_context.hash(password) Hash password with bcrypt
Bcrypt имеет ограничение: пароль не может быть длиннее 72 байт.
Если пароль превышает 72 байта, он будет автоматически обрезан до первых 72 байт.
ВАЖНО: Если пароль обрезан при регистрации, то при входе нужно ввести
тот же пароль (который также будет обрезан до 72 байт), иначе проверка не сработает.
Для избежания проблем рекомендуется использовать пароли до 24 символов,
что обычно не превышает 72 байта даже для UTF-8 символов.
"""
# Bcrypt has a maximum password length of 72 bytes
# Truncate if necessary (encode to bytes first to get accurate byte length)
print(f"[Auth] 🔍 hash_password вызван:")
print(f"[Auth] Пароль (repr): {repr(password)}")
print(f"[Auth] Длина в символах: {len(password)}")
password_bytes = password.encode('utf-8')
original_length = len(password_bytes)
print(f"[Auth] Длина в байтах: {original_length}")
print(f"[Auth] Байты (hex): {password_bytes.hex()}")
if original_length > 72:
# Обрезаем до первых 72 байт
password = password_bytes[:72].decode('utf-8', errors='ignore')
print(f"[Auth] ⚠️ Пароль обрезан до 72 байт (было {original_length} байт)")
print(f"[Auth] ⚠️ ВНИМАНИЕ: При входе используйте тот же пароль, он также будет обрезан")
else:
print(f"[Auth] ✅ Пароль в пределах лимита (72 байта)")
try:
result = pwd_context.hash(password)
print(f"[Auth] ✅ Пароль успешно захеширован")
return result
except Exception as e:
print(f"[Auth] ❌ Ошибка при хешировании: {type(e).__name__}: {e}")
import traceback
traceback.print_exc()
raise
def verify_password(plain_password: str, hashed_password: str) -> bool: def verify_password(plain_password: str, hashed_password: str) -> bool:
"""Verify password against hash""" """
Verify password against hash
Bcrypt имеет ограничение: пароль не может быть длиннее 72 байт.
Если пароль превышает 72 байта, он будет автоматически обрезан до первых 72 байт.
Это гарантирует, что проверка сработает даже если пароль был обрезан при регистрации.
"""
# Bcrypt has a maximum password length of 72 bytes
# Truncate if necessary (encode to bytes first to get accurate byte length)
password_bytes = plain_password.encode('utf-8')
if len(password_bytes) > 72:
# Обрезаем до первых 72 байт (так же, как при хешировании)
plain_password = password_bytes[:72].decode('utf-8', errors='ignore')
print(f"[Auth] ⚠️ Пароль при проверке обрезан до 72 байт (было {len(password_bytes)} байт)")
return pwd_context.verify(plain_password, hashed_password) return pwd_context.verify(plain_password, hashed_password)

View File

@ -736,8 +736,13 @@ export default function App() {
return; return;
} }
if (authForm.password.length < 6) { if (authForm.password.length < 8) {
setError('Пароль должен содержать минимум 6 символов'); setError('Пароль должен содержать минимум 8 символов');
return;
}
if (authForm.password.length > 24) {
setError('Пароль должен содержать максимум 24 символа');
return; return;
} }
@ -1547,7 +1552,7 @@ export default function App() {
type={authForm.showPassword ? 'text' : 'password'} type={authForm.showPassword ? 'text' : 'password'}
value={authForm.password} value={authForm.password}
onChange={(e) => setAuthForm((prev) => ({ ...prev, password: e.target.value }))} onChange={(e) => setAuthForm((prev) => ({ ...prev, password: e.target.value }))}
placeholder="Минимум 6 символов" placeholder="От 8 до 24 символов"
style={{ style={{
padding: '12px', padding: '12px',
borderRadius: '8px', borderRadius: '8px',