docs: 添加RPA自动化脚本CSRF保护解决方案文档
在README.md中添加关于RPA/自动化脚本调用API时遇到的CSRF保护问题及解决方案的详细文档。包括三种解决方案、安全建议和常见问题解答,帮助开发者快速解决自动化脚本调用API时的403错误问题。
This commit is contained in:
131
README.md
131
README.md
@@ -1457,6 +1457,137 @@ celery -A diary_family flower --port=5555
|
|||||||
|
|
||||||
访问 http://your-server:5555 查看任务监控界面。
|
访问 http://your-server:5555 查看任务监控界面。
|
||||||
|
|
||||||
|
## RPA/自动化脚本 CSRF保护问题解决方案
|
||||||
|
|
||||||
|
当使用RPA(机器人流程自动化)或自动化脚本调用系统API时,可能会遇到Django的CSRF(跨站请求伪造)保护机制拦截的问题。
|
||||||
|
|
||||||
|
### 问题现象
|
||||||
|
|
||||||
|
- 调用API返回 **403 Forbidden** 错误
|
||||||
|
- 错误信息包含 `CSRF verification failed` 或 `Forbidden (CSRF cookie not set.)`
|
||||||
|
- RPA工具无法正常提交数据到 `/api/v1/summary/submit/`
|
||||||
|
|
||||||
|
### 问题原因
|
||||||
|
|
||||||
|
Django默认启用CSRF保护中间件(`CsrfViewMiddleware`),所有POST请求都需要提供有效的CSRF令牌。但自动化脚本和RPA工具无法像浏览器一样获取和携带CSRF令牌。
|
||||||
|
|
||||||
|
### 解决方案
|
||||||
|
|
||||||
|
#### 方案一:为API视图添加CSRF豁免(推荐)
|
||||||
|
|
||||||
|
修改 `core/views.py` 文件,为API提交接口添加 `@csrf_exempt` 装饰器:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
|
# 在 api_submit_summary 函数前添加装饰器
|
||||||
|
@csrf_exempt
|
||||||
|
def api_submit_summary(request):
|
||||||
|
"""API提交汇总记录 - 仅接受指定分类和发言人的记录"""
|
||||||
|
# ... 原有代码保持不变 ...
|
||||||
|
```
|
||||||
|
|
||||||
|
**操作步骤**:
|
||||||
|
|
||||||
|
1. 打开 `core/views.py` 文件
|
||||||
|
2. 确保文件顶部已导入 `csrf_exempt`:
|
||||||
|
```python
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
```
|
||||||
|
3. 在 `api_submit_summary` 函数定义前添加 `@csrf_exempt` 装饰器
|
||||||
|
4. 保存文件并重启Gunicorn服务:
|
||||||
|
```bash
|
||||||
|
sudo supervisorctl restart diary-family
|
||||||
|
# 或
|
||||||
|
sudo systemctl restart gunicorn
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 方案二:配置CSRF信任域名
|
||||||
|
|
||||||
|
如果不想完全禁用CSRF保护,可以在 `settings.py` 中配置信任的域名:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 在 settings.py 中添加
|
||||||
|
CSRF_TRUSTED_ORIGINS = [
|
||||||
|
'https://your-domain.com',
|
||||||
|
'https://*.your-domain.com',
|
||||||
|
]
|
||||||
|
|
||||||
|
# 如果使用IP访问,添加IP地址
|
||||||
|
CSRF_TRUSTED_ORIGINS = [
|
||||||
|
'http://192.168.1.100',
|
||||||
|
'http://localhost',
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 方案三:为特定URL路径禁用CSRF
|
||||||
|
|
||||||
|
在 `core/views.py` 中创建一个通用的API装饰器:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
def api_exempt(view_func):
|
||||||
|
"""
|
||||||
|
API接口CSRF豁免装饰器
|
||||||
|
用于标记不需要CSRF保护的API接口
|
||||||
|
"""
|
||||||
|
@wraps(view_func)
|
||||||
|
@csrf_exempt
|
||||||
|
def wrapped_view(request, *args, **kwargs):
|
||||||
|
# 可以在这里添加API认证逻辑
|
||||||
|
return view_func(request, *args, **kwargs)
|
||||||
|
return wrapped_view
|
||||||
|
|
||||||
|
# 使用方式
|
||||||
|
@api_exempt
|
||||||
|
def api_submit_summary(request):
|
||||||
|
# ... 原有代码 ...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 安全建议
|
||||||
|
|
||||||
|
1. **仅对必要的API接口禁用CSRF保护**,不要对整个视图或应用禁用
|
||||||
|
2. **添加API认证机制**(如API Key、Token认证)替代CSRF保护
|
||||||
|
3. **限制API访问来源IP**,在Nginx或防火墙层面进行限制
|
||||||
|
4. **使用HTTPS协议**确保数据传输安全
|
||||||
|
5. **记录API访问日志**,便于审计和排查问题
|
||||||
|
|
||||||
|
### 验证修复
|
||||||
|
|
||||||
|
修改配置后,使用以下命令验证API是否可正常访问:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 测试API接口
|
||||||
|
curl -X POST http://your-server/api/v1/summary/submit/ \
|
||||||
|
-d "content=测试内容"
|
||||||
|
|
||||||
|
# 预期返回
|
||||||
|
{"success": true, "message": "提交成功", "id": 123}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
|
||||||
|
#### Q1: 添加 `@csrf_exempt` 后是否安全?
|
||||||
|
**A**: 对于内部API和自动化脚本调用的接口,添加 `@csrf_exempt` 是安全的,因为:
|
||||||
|
- API接口通常需要其他形式的认证(如API Key)
|
||||||
|
- 自动化脚本运行在受控环境中
|
||||||
|
- 可以结合IP白名单、请求频率限制等安全措施
|
||||||
|
|
||||||
|
#### Q2: 如何在RPA工具中处理CSRF?
|
||||||
|
**A**: 推荐在服务器端禁用CSRF保护(方案一),而不是在RPA工具中处理CSRF令牌。这样可以简化RPA脚本的复杂度。
|
||||||
|
|
||||||
|
#### Q3: 修改后需要重启服务吗?
|
||||||
|
**A**: 是的,Python代码修改后需要重启Gunicorn或uWSGI服务才能生效:
|
||||||
|
```bash
|
||||||
|
sudo supervisorctl restart all
|
||||||
|
# 或
|
||||||
|
sudo systemctl restart gunicorn
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## API接口文档
|
## API接口文档
|
||||||
|
|
||||||
系统提供RESTful API接口,用于外部客户端提交汇总记录。
|
系统提供RESTful API接口,用于外部客户端提交汇总记录。
|
||||||
|
|||||||
Reference in New Issue
Block a user