feat: 开发采集、采集箱和商品编辑功能
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
"""JWT 鉴权 + 店铺凭证 AES-GCM 加解密。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
import os
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
import jwt
|
||||
|
||||
from config import get_settings
|
||||
|
||||
|
||||
# ── JWT ──
|
||||
|
||||
def create_access_token(subject: str = "app") -> tuple[str, int]:
|
||||
"""签发 JWT。返回 (token, 过期 epoch 秒)。"""
|
||||
settings = get_settings()
|
||||
expires = datetime.now(timezone.utc) + timedelta(minutes=settings.jwt_expire_minutes)
|
||||
payload = {"sub": subject, "exp": expires}
|
||||
token = jwt.encode(payload, settings.secret_key, algorithm="HS256")
|
||||
return token, int(expires.timestamp())
|
||||
|
||||
|
||||
def decode_token(token: str) -> dict:
|
||||
"""校验并解析 JWT;失败抛 jwt.PyJWTError。"""
|
||||
settings = get_settings()
|
||||
return jwt.decode(token, settings.secret_key, algorithms=["HS256"])
|
||||
|
||||
|
||||
# ── AES-GCM 店铺凭证加密 ──
|
||||
|
||||
def _derive_key() -> bytes:
|
||||
settings = get_settings()
|
||||
return hashlib.sha256(settings.secret_key.encode("utf-8")).digest()
|
||||
|
||||
|
||||
def encrypt_secret(plaintext: str) -> str:
|
||||
"""AES-GCM 加密,返回 base64(nonce + ciphertext + tag)。"""
|
||||
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
||||
|
||||
key = _derive_key()
|
||||
nonce = os.urandom(12)
|
||||
aesgcm = AESGCM(key)
|
||||
ct = aesgcm.encrypt(nonce, plaintext.encode("utf-8"), None)
|
||||
return base64.b64encode(nonce + ct).decode("ascii")
|
||||
|
||||
|
||||
def decrypt_secret(ciphertext: str) -> str:
|
||||
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
||||
|
||||
key = _derive_key()
|
||||
raw = base64.b64decode(ciphertext.encode("ascii"))
|
||||
nonce, ct = raw[:12], raw[12:]
|
||||
aesgcm = AESGCM(key)
|
||||
return aesgcm.decrypt(nonce, ct, None).decode("utf-8")
|
||||
Reference in New Issue
Block a user