|
from functools import wraps
|
|
from flask import request, jsonify
|
|
import os
|
|
import time
|
|
import hashlib
|
|
import hmac
|
|
|
|
|
|
def get_api_key():
|
|
return os.getenv('API_KEY', 'UZXJfw3YNX80DLfN')
|
|
|
|
|
|
def require_api_key(f):
|
|
"""需要API密钥验证的装饰器"""
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
api_key = request.headers.get('X-API-Key')
|
|
if not api_key:
|
|
return jsonify({'error': '缺少API密钥'}), 401
|
|
|
|
if api_key != get_api_key():
|
|
return jsonify({'error': '无效的API密钥'}), 403
|
|
|
|
return f(*args, **kwargs)
|
|
return decorated_function
|
|
|
|
|
|
def generate_hmac_signature(data, secret_key=None):
|
|
if secret_key is None:
|
|
secret_key = os.getenv('HMAC_SECRET', 'default_hmac_secret_for_development')
|
|
|
|
if isinstance(data, dict):
|
|
|
|
data = '&'.join(f"{k}={v}" for k, v in sorted(data.items()))
|
|
|
|
|
|
signature = hmac.new(
|
|
secret_key.encode(),
|
|
data.encode(),
|
|
hashlib.sha256
|
|
).hexdigest()
|
|
|
|
return signature
|
|
|
|
|
|
def verify_hmac_signature(request_signature, data, secret_key=None):
|
|
expected_signature = generate_hmac_signature(data, secret_key)
|
|
return hmac.compare_digest(request_signature, expected_signature)
|
|
|
|
|
|
def require_hmac_auth(f):
|
|
"""需要HMAC认证的装饰器"""
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
request_signature = request.headers.get('X-HMAC-Signature')
|
|
if not request_signature:
|
|
return jsonify({'error': '缺少HMAC签名'}), 401
|
|
|
|
|
|
data = request.get_json(silent=True) or {}
|
|
|
|
|
|
timestamp = request.headers.get('X-Timestamp')
|
|
if not timestamp:
|
|
return jsonify({'error': '缺少时间戳'}), 401
|
|
|
|
|
|
current_time = int(time.time())
|
|
if abs(current_time - int(timestamp)) > 300:
|
|
return jsonify({'error': '时间戳已过期'}), 401
|
|
|
|
|
|
verification_data = {**data, 'timestamp': timestamp}
|
|
|
|
|
|
if not verify_hmac_signature(request_signature, verification_data):
|
|
return jsonify({'error': '签名无效'}), 403
|
|
return f(*args, **kwargs)
|
|
return decorated_function |