重构CryptUtils类,替换原有的passlib密码哈希逻辑为直接使用bcrypt库;添加密码字节长度限制以符合bcrypt原生72字节上限;更新pyproject.toml配置,新增bcrypt依赖并将passlib设为可选依赖;统一代码缩进格式
58 lines
1.5 KiB
Python
58 lines
1.5 KiB
Python
from datetime import timedelta, datetime, timezone
|
|
from typing import TypedDict, Literal, TypeAlias
|
|
|
|
import bcrypt
|
|
import jwt
|
|
|
|
from app.config.env import env
|
|
|
|
BCRYPT_MAX_BYTES = 72
|
|
|
|
AccessTokenType: TypeAlias = Literal["access", "refresh", "verify", "api"]
|
|
|
|
|
|
class TokenInfo(TypedDict):
|
|
username: str
|
|
exp: datetime
|
|
type: AccessTokenType
|
|
|
|
|
|
def _safe_password_bytes(password: str) -> bytes:
|
|
data = password.encode("utf-8")
|
|
if len(data) > BCRYPT_MAX_BYTES:
|
|
data = data[:BCRYPT_MAX_BYTES]
|
|
return data
|
|
|
|
|
|
class CryptUtils:
|
|
@staticmethod
|
|
def get_password_hash(password: str):
|
|
return bcrypt.hashpw(_safe_password_bytes(password), bcrypt.gensalt()).decode(
|
|
"utf-8"
|
|
)
|
|
|
|
@staticmethod
|
|
def verify_password(plain_password: str, hashed_password: str):
|
|
try:
|
|
return bcrypt.checkpw(
|
|
_safe_password_bytes(plain_password), hashed_password.encode("utf-8")
|
|
)
|
|
except ValueError:
|
|
return False
|
|
except Exception:
|
|
return False
|
|
|
|
@staticmethod
|
|
def create_token(username: str, type: AccessTokenType, expires_delta: timedelta):
|
|
data: TokenInfo = {
|
|
"username": username,
|
|
"type": type,
|
|
"exp": datetime.now(timezone.utc) + expires_delta,
|
|
}
|
|
return jwt.encode(data, env.jwt_secret_key, env.jwt_algorithm)
|
|
|
|
@staticmethod
|
|
def get_token_info(token: str) -> TokenInfo:
|
|
data = jwt.decode(token, env.jwt_secret_key, algorithms=[env.jwt_algorithm])
|
|
return data
|