Files
server-core/app/infrastructure/security.py
T
Pine 980a2db6d9 refactor: 平台应用异步四层架构(接口/业务/领域/基础设施)
- 基础设施层 async:SQLAlchemy 异步引擎/会话、33 Repository async 化、models/security/seed 迁入 infrastructure、新增 cache.py(redis.asyncio) 与 oss.py(aioboto3)
- 接口层:routers 迁 api/routers 并全 async,dependencies 迁 api/dependencies(get_db/get_current_user async)
- 依赖:sqlalchemy[asyncio]/aiosqlite/asyncmy/redis/aioboto3;config 异步 URL + Redis/OSS 配置
- 删除废弃:旧同步 db/dependencies/repositories/storage
- 验证:平台 19 路由 + 培训 48 路由全注册;/health /auth/login /auth/me /admin/tasks /notifications 等接口 async 可用
2026-08-23 23:52:58 +08:00

32 lines
1.1 KiB
Python

# -*- coding: utf-8 -*-
"""密码哈希与令牌生成(仅用标准库,无额外依赖)。
- 密码:加盐 SHA-256,与 PineAgents 主后端历史实现一致(salted SHA-256)。
- 令牌:不透明随机串,存于 tokens.json。下一阶段换成数据库时,
该随机串即 ``tokens.token`` 列的主键值,语义与 JWT/会话表一致。
"""
from __future__ import annotations
import hashlib
import hmac
import secrets
def hash_password(password: str, salt: str | None = None) -> tuple[str, str]:
"""计算 (hash_hex, salt_hex)。未提供 salt 时自动生成随机盐。"""
if salt is None:
salt = secrets.token_hex(16)
digest = hashlib.sha256((salt + password).encode("utf-8")).hexdigest()
return digest, salt
def verify_password(password: str, stored_hash: str, salt: str) -> bool:
"""常数时间比较,防时序侧信道。"""
digest, _ = hash_password(password, salt)
return hmac.compare_digest(digest, stored_hash)
def generate_token() -> str:
"""生成不透明访问令牌(URL-safe,约 64 字符)。"""
return secrets.token_urlsafe(48)