feat: 完善代理商端业务逻辑与前后端框架
主要更新: - 更新代理商端文档,明确项目由品牌方分配流程 - 新增Brief配置详情页(已配置)设计稿 - 完善工作台紧急待办中品牌新任务功能 - 整理Pencil设计文件中代理商端页面顺序 - 新增后端FastAPI框架及核心API - 新增前端Next.js页面和组件库 - 添加.gitignore排除构建和缓存文件 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
d52509d630
commit
e4959d584f
@@ -0,0 +1,9 @@
|
||||
"""
|
||||
工具模块
|
||||
"""
|
||||
from app.utils.crypto import encrypt_api_key, decrypt_api_key
|
||||
|
||||
__all__ = [
|
||||
"encrypt_api_key",
|
||||
"decrypt_api_key",
|
||||
]
|
||||
@@ -0,0 +1,84 @@
|
||||
"""
|
||||
加密工具
|
||||
API Key 加解密
|
||||
"""
|
||||
import base64
|
||||
import os
|
||||
from cryptography.fernet import Fernet
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
||||
|
||||
from app.config import settings
|
||||
|
||||
|
||||
def _get_fernet() -> Fernet:
|
||||
"""
|
||||
获取 Fernet 加密器
|
||||
使用应用的 SECRET_KEY 派生加密密钥
|
||||
"""
|
||||
# 使用 PBKDF2 从 SECRET_KEY 派生 32 字节密钥
|
||||
kdf = PBKDF2HMAC(
|
||||
algorithm=hashes.SHA256(),
|
||||
length=32,
|
||||
salt=b"miaosi-api-key-salt", # 固定 salt,生产环境应配置为环境变量
|
||||
iterations=100000,
|
||||
)
|
||||
key = base64.urlsafe_b64encode(
|
||||
kdf.derive(settings.SECRET_KEY.encode())
|
||||
)
|
||||
return Fernet(key)
|
||||
|
||||
|
||||
def encrypt_api_key(api_key: str) -> str:
|
||||
"""
|
||||
加密 API Key
|
||||
|
||||
Args:
|
||||
api_key: 明文 API Key
|
||||
|
||||
Returns:
|
||||
加密后的 Base64 字符串
|
||||
"""
|
||||
if not api_key:
|
||||
return ""
|
||||
|
||||
fernet = _get_fernet()
|
||||
encrypted = fernet.encrypt(api_key.encode())
|
||||
return encrypted.decode()
|
||||
|
||||
|
||||
def decrypt_api_key(encrypted: str) -> str:
|
||||
"""
|
||||
解密 API Key
|
||||
|
||||
Args:
|
||||
encrypted: 加密的 API Key
|
||||
|
||||
Returns:
|
||||
明文 API Key
|
||||
"""
|
||||
if not encrypted:
|
||||
return ""
|
||||
|
||||
fernet = _get_fernet()
|
||||
decrypted = fernet.decrypt(encrypted.encode())
|
||||
return decrypted.decode()
|
||||
|
||||
|
||||
def mask_api_key(api_key: str) -> str:
|
||||
"""
|
||||
脱敏 API Key
|
||||
|
||||
Args:
|
||||
api_key: API Key(明文或加密均可)
|
||||
|
||||
Returns:
|
||||
脱敏后的字符串,如 "sk-1234****5678"
|
||||
"""
|
||||
if not api_key:
|
||||
return ""
|
||||
|
||||
if len(api_key) <= 8:
|
||||
return "****"
|
||||
|
||||
return f"{api_key[:4]}****{api_key[-4:]}"
|
||||
Reference in New Issue
Block a user