第 18 章 · 安全最佳实践
本章目标:掌握 HTTP 请求中的安全风险及防护措施。
18.1 HTTPS 强制
python
import requests
# 永远使用 HTTPS
resp = requests.get('https://api.example.com/data')
# 禁止重定向到 HTTP(防止降级攻击)
resp = requests.get('https://api.example.com/data', allow_redirects=True)18.2 敏感信息保护
python
import os
import requests
# 错误:硬编码密钥
# resp = requests.get('https://api.example.com', headers={'Authorization': 'Bearer sk-xxx'})
# 正确:从环境变量读取
api_key = os.environ.get('API_KEY')
if not api_key:
raise ValueError('请设置 API_KEY 环境变量')
resp = requests.get(
'https://api.example.com',
headers={'Authorization': f'Bearer {api_key}'}
)18.3 URL 注入防护
python
import requests
from urllib.parse import urlencode
# 危险:用户输入直接拼接 URL
# url = f'https://api.example.com/search?q={user_input}'
# 安全:使用 params 参数
params = {'q': user_input}
resp = requests.get('https://api.example.com/search', params=params)18.4 SSL 证书验证
python
import requests
# 生产环境必须验证证书
resp = requests.get('https://api.example.com', verify=True) # 默认
# 内网自签证书:指定 CA bundle
resp = requests.get('https://internal.example.com', verify='/path/to/ca.pem')
# 永远不要在生产环境设置 verify=False18.5 请求限制与防刷
python
import requests
import time
def rate_limited_get(url: str, max_retries: int = 3):
for attempt in range(max_retries):
try:
resp = requests.get(url, timeout=10)
if resp.status_code == 429: # 速率限制
wait = int(resp.headers.get('Retry-After', 60))
time.sleep(wait)
continue
resp.raise_for_status()
return resp
except requests.exceptions.RequestException as e:
if attempt == max_retries - 1:
raise
time.sleep(2 ** attempt) # 指数退避18.6 本章小结
- 始终使用 HTTPS,禁止降级到 HTTP;
- API 密钥等敏感信息从环境变量读取;
- 使用 params 而非字符串拼接构建 URL;
- 生产环境必须启用 SSL 证书验证。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. 生产环境正确的 SSL 验证方式是?
2. 防止 URL 注入的最佳做法是?
3. API 密钥应该存储在?
4. HTTP 429 状态码表示?
🛠️ 动手实践
- 实现环境变量读取 API Key 的安全模式。
- 测试 URL 编码与字符串拼接的区别。
- 实现带速率限制的请求函数。
完成练习后,进入下一章:生产部署与监控。