| 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 |