如何在Django REST Framework中实现基于Token认证的媒体文件下载权限控制
Django+DRF Token认证下限制媒体文件下载的实现方案
要实现仅让持有有效Token的用户下载PDF媒体文件,核心思路是不直接通过静态服务器(Nginx/Apache)暴露媒体文件,而是通过DRF视图接管下载请求,利用DRF的Token认证机制验证用户身份后再返回文件内容。具体步骤如下:
1. 调整媒体文件访问逻辑
保留原MEDIA_ROOT存储文件,但不再通过静态服务器直接映射MEDIA_URL,改为通过DRF视图处理所有媒体文件的下载请求。
2. 编写DRF认证视图处理文件下载
创建继承APIView的视图,启用Token认证和登录权限校验,同时处理文件读取与安全校验:
from rest_framework.views import APIView from rest_framework.authentication import TokenAuthentication from rest_framework.permissions import IsAuthenticated from django.http import StreamingHttpResponse, Http404 import os from django.conf import settings class ProtectedPDFDownloadView(APIView): authentication_classes = [TokenAuthentication] permission_classes = [IsAuthenticated] def get(self, request, filename): # 构建完整文件路径(假设PDF都存在MEDIA_ROOT下的pdfs子目录) file_path = os.path.join(settings.MEDIA_ROOT, 'pdfs', filename) # 安全校验:防止路径遍历攻击 if not os.path.abspath(file_path).startswith(os.path.abspath(settings.MEDIA_ROOT)): raise Http404("文件不存在") # 检查文件是否存在且为有效文件 if not os.path.exists(file_path) or not os.path.isfile(file_path): raise Http404("文件不存在") # 流式返回文件,避免大文件占用过多内存 def file_iterator(file_path, chunk_size=8192): with open(file_path, 'rb') as f: while chunk := f.read(chunk_size): yield chunk # 设置响应头,指定文件类型和下载行为 response = StreamingHttpResponse(file_iterator(file_path)) response['Content-Type'] = 'application/pdf' # 若需浏览器直接预览,将attachment改为inline response['Content-Disposition'] = f'attachment; filename="{filename}"' return response
3. 配置URL路由
将受保护的PDF下载请求路由到上述视图:
# 在项目或app的urls.py中添加路由 from django.urls import path from .views import ProtectedPDFDownloadView urlpatterns = [ # 其他业务路由... path('protected-pdfs/<str:filename>/', ProtectedPDFDownloadView.as_view(), name='protected_pdf_download'), ]
4. 前端请求调整
前端不再直接请求原MEDIA_URL路径,改为请求上述配置的/protected-pdfs/文件名/路径,并在请求头中携带Authorization: Token <用户Token值>。
额外注意事项
- 路径安全:必须保留路径遍历校验,防止恶意用户构造参数访问服务器敏感文件。
- 性能优化:大文件使用
StreamingHttpResponse流式返回,降低服务器内存占用。 - 权限细化:若需特定用户仅能下载特定文件,可在视图
get方法中添加额外校验逻辑(比如关联用户与文件的权限表)。
内容的提问来源于stack exchange,提问作者mohamadreza ch
相关产品推荐
相关产品推荐

