Files
djangoadmin-wiki/DjangoAdmin_Django_NaiveVue/zh/volume3/request-flow.md
T
2026-09-12 23:12:15 +08:00

337 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第四章 架构设计 - 请求处理流程
## 4.1 请求处理全链路
一个完整的 HTTP 请求在 系统中的处理流程如下:
```
浏览器
|
| (1) 发起HTTP请求 (携带 Authorization: Bearer <token>)
v
Nginx
|
| (2) 反向代理,静态资源由Nginx处理,API请求转发到Django
v
Django WSGI
|
| (3) 进入中间件链
v
CORS中间件 (corsheaders.middleware.CorsMiddleware)
|
| (4) 处理跨域请求,添加CORS响应头
v
check_login装饰器 (middleware/login_middleware.py)
|
| (5) 验证JWT token有效性
v
URL路由匹配 (application/urls.py)
|
| (6) 根据URL分发到对应视图类
v
PermissionRequired混入类 (middleware/permission_middleware.py)
|
| (7) 验证用户权限节点
v
View视图类 (views.py)
|
| (8) 解析请求参数,调用Service
v
Service服务函数 (services.py)
|
| (9) 执行业务逻辑,操作数据库
v
R.ok()/R.failed() (utils/R.py)
|
| (10) 构造统一JSON响应
v
JsonResponse
|
| (11) 返回响应数据
v
浏览器
```
## 4.2 中间件处理顺序
根据 `application/settings.py` 的配置,中间件按以下顺序执行:
```python
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 1. CORS跨域处理
'django.middleware.security.SecurityMiddleware', # 2. 安全处理
'django.contrib.sessions.middleware.SessionMiddleware', # 3. Session处理
'django.middleware.common.CommonMiddleware', # 4. 通用处理
# 'django.middleware.csrf.CsrfViewMiddleware', # CSRF已禁用(使用JWT)
'django.contrib.auth.middleware.AuthenticationMiddleware', # 5. 认证处理
'django.contrib.messages.middleware.MessageMiddleware', # 6. 消息处理
'django.middleware.clickjacking.XFrameOptionsMiddleware', # 7. 点击劫持防护
]
```
**注意**:`check_login` 和 `PermissionRequired` 不是 Django 中间件,而是通过装饰器和混入类实现的,作用于视图层面。
## 4.3 JWT 认证流程
### 4.3.1 登录认证
```python
# 1. 用户提交用户名密码
POST /login
{
"username": "admin",
"password": "123456",
"captcha": "abc123"
}
# 2. 验证通过后生成JWT Token
from utils.jwt import create_token
payload = {
'userId': user.id,
'username': user.username,
'realname': user.realname
}
token = create_token(payload, timeout=20) # 20分钟过期
# 3. 返回Token给前端
{
"code": 0,
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
},
"msg": "登录成功"
}
```
### 4.3.2 请求认证
```python
# 1. 前端在请求头中携带Token
headers = {
"Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
# 2. check_login装饰器验证Token
def check_login(func):
def wrapper(request, *args, **kwargs):
# 忽略不需要认证的URL
ignoreURL = ['/login', '/captcha']
if request.path not in ignoreURL:
# 从请求头获取Token
access_token = request.headers['Authorization']
access_token = access_token.replace('Bearer ', "")
# 验证Token
result = parse_payload(access_token)
if result['code'] != 0:
return R.failed(code=401, msg=result['msg'])
return func(request, *args, **kwargs)
return wrapper
```
### 4.3.3 Token 黑名单检查
```python
# 1. 验证Token时先检查黑名单
def parse_payload(token):
# 检查Token是否在黑名单中
if is_token_blacklisted(token):
return {'code': -1, 'msg': 'token已失效,请重新登录'}
# 解密验证JWT令牌
verified_payload = jwt.decode(token, JWT_SALT, algorithms=[JWT_ALGORITHM])
return {'code': 0, 'data': verified_payload}
# 2. 黑名单检查使用Redis
def is_token_blacklisted(token):
redis = get_redis_connection("default")
fingerprint = hashlib.sha256(token.encode('utf-8')).hexdigest()
key = f'token:blacklist:{fingerprint}'
return redis.exists(key) > 0
```
## 4.4 权限验证流程
### 4.4.1 权限节点定义
每个操作对应一个权限节点,格式为 `sys:<module>:<action>`:
```python
# 示例:案例模块的权限节点
permission_required = ("sys:example:page",) # 分页查询
permission_required = ("sys:example:detail",) # 详情查询
permission_required = ("sys:example:add",) # 添加
permission_required = ("sys:example:update",) # 更新
permission_required = ("sys:example:delete",) # 删除
permission_required = ("sys:example:status",) # 状态更新
```
### 4.4.2 权限验证逻辑
```python
class PermissionRequired(PermissionRequiredMixin):
def has_permission(self):
# 获取所需权限节点
permissions = self.get_permission_required()
# 获取当前用户ID
user_id = get_user_id(self.request)
# 超级管理员(ID=1)自动放行
if user_id and user_id != 1:
# 获取用户权限列表
permission_list = services.get_user_permissions(user_id)
# 检查是否拥有所需权限
for permission in permissions:
if permission not in permission_list:
return False
return True
```
### 4.4.3 权限获取逻辑
```python
# application/menu/services.py
def get_user_permissions(user_id):
if user_id == 1:
# 超级管理员拥有所有权限
menu_list = Menu.objects.filter(is_delete=False, type=1, status=0).values()
return [item['permission'] for item in menu_list]
else:
# 普通用户从角色关联中获取权限
sql = '''
SELECT m.* FROM django_menu AS m
INNER JOIN django_role_menu AS rm ON m.id=rm.menu_id
INNER JOIN django_user_role AS ur ON ur.role_id=rm.role_id
WHERE ur.user_id=%s AND (m.type=1 OR (m.type=0 AND m.permission!=''))
AND m.status=0 AND m.is_delete=0
'''
menu_list = Menu.objects.raw(sql, [user_id])
return [item.permission for item in menu_list]
```
## 4.5 业务处理流程
以"添加案例"为例,完整的业务处理流程:
```
1. View层 (ExampleAddView.post)
+-- 检查演示模式 (DJANGO_DEMO)
+-- 调用 Service: services.add_example(request)
2. Service层 (add_example)
+-- 解析请求体: parse_request_body(request)
+-- 表单验证: forms.ExampleForm(data)
+-- 处理文件: save_file(avatar, "example")
+-- 创建记录: Example.objects.create(...)
+-- 返回结果: R.ok(msg="创建成功")
3. Model层 (Example)
+-- Django ORM 生成 SQL
+-- MySQL 执行 INSERT
+-- 自动生成 create_time、update_time
```
## 4.6 响应格式规范
所有 API 接口返回统一的 JSON 格式:
### 成功响应
```json
{
"code": 0,
"data": {
"id": 1,
"name": "案例名称",
"status": 1
},
"msg": "操作成功",
"ok": true
}
```
### 分页响应
```json
{
"code": 0,
"data": {
"records": [
{"id": 1, "name": "案例1"},
{"id": 2, "name": "案例2"}
],
"total": 100,
"size": 10,
"current": 1,
"pages": 10
},
"msg": "操作成功",
"ok": true
}
```
### 失败响应
```json
{
"code": 1,
"data": null,
"msg": "操作失败",
"ok": false
}
```
### 认证失败响应
```json
{
"code": 401,
"data": null,
"msg": "token已失效,请重新登录",
"ok": false
}
```
## 4.7 异常处理机制
### 4.7.1 全局异常处理
```python
# Service层统一使用 try-except 捕获异常
def add_example(request):
try:
# 业务逻辑
Example.objects.create(...)
return R.ok(msg="创建成功")
except Exception as e:
logging.error(f"添加案例异常: {str(e)}")
return R.failed(msg="添加失败,请稍后重试")
```
### 4.7.2 表单验证异常
```python
# 表单验证失败时返回具体错误信息
form = ExampleForm(data)
if not form.is_valid():
return R.failed(msg=regular.get_err(form))
```
### 4.7.3 数据库异常
```python
# 数据库操作异常被捕获并返回友好提示
try:
instance.save()
except IntegrityError as e:
return R.failed(msg="数据完整性错误")
except Exception as e:
logging.error(f"数据库异常: {str(e)}")
return R.failed(msg="操作失败,请稍后重试")
```