feature:基本框架
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""业务逻辑层:每个 Agent/模块一个 service(rag / profile / trade / risk / advisor / memory…),随 Phase 落地。"""
|
||||
@@ -0,0 +1,46 @@
|
||||
"""认证服务:JWT 签发/校验(HS256)+ 密码哈希/校验。
|
||||
|
||||
密码用 stdlib PBKDF2(免 bcrypt 依赖),存储格式自描述:
|
||||
pbkdf2_sha256$600000$<salt_hex>$<digest_hex>
|
||||
"""
|
||||
import hashlib
|
||||
import hmac
|
||||
import secrets
|
||||
import time
|
||||
|
||||
import jwt
|
||||
|
||||
from config.settings import settings
|
||||
|
||||
_ITERATIONS = 600_000
|
||||
|
||||
|
||||
# ---- JWT ----
|
||||
def create_token(user_id: int, *, extra: dict | None = None) -> str:
|
||||
"""签发 token:仅存 user_id + iat/exp,用户信息校验时按 id 回查 sys_user。"""
|
||||
now = int(time.time())
|
||||
payload = {"user_id": user_id, "iat": now, "exp": now + settings.jwt.expire_seconds}
|
||||
if extra:
|
||||
payload.update(extra)
|
||||
return jwt.encode(payload, settings.jwt.secret, algorithm=settings.jwt.algorithm)
|
||||
|
||||
|
||||
def decode_token(token: str) -> dict:
|
||||
"""校验签名 + 过期,返回 claims;任何失败抛异常(调用方转 401)。"""
|
||||
return jwt.decode(token, settings.jwt.secret, algorithms=[settings.jwt.algorithm])
|
||||
|
||||
|
||||
# ---- 密码 ----
|
||||
def hash_password(password: str) -> str:
|
||||
salt = secrets.token_hex(16)
|
||||
digest = hashlib.pbkdf2_hmac("sha256", password.encode(), bytes.fromhex(salt), _ITERATIONS)
|
||||
return f"pbkdf2_sha256${_ITERATIONS}${salt}${digest.hex()}"
|
||||
|
||||
|
||||
def verify_password(password: str, stored: str) -> bool:
|
||||
try:
|
||||
_, iters, salt, digest = stored.split("$")
|
||||
except ValueError:
|
||||
return False
|
||||
calc = hashlib.pbkdf2_hmac("sha256", password.encode(), bytes.fromhex(salt), int(iters))
|
||||
return hmac.compare_digest(calc.hex(), digest)
|
||||
Reference in New Issue
Block a user