私有网盘安全核心在于路径隔离、分片上传和分享权限控制:必须动态生成用户级存储路径,禁用django内存缓存并用原始流处理大文件,分享链接需绑定时效、下载权限、密码及访问次数限制。

能跑起来的私有网盘,核心不在框架选型,而在文件存储路径、上传流处理和权限隔离这三处。Django 本身不存文件,FileSystemStorage 默认写到 media/ 目录下,但直接暴露该目录或不做路径隔离,会导致用户 A 能通过构造 URL 访问用户 B 的文件——这是最常被忽略的安全缺口。
文件存储必须做用户级路径隔离
Django 的 FileSystemStorage 支持自定义 location 和 base_url,但默认配置是全局共享的。不隔离路径,等于把所有用户的文件扔进同一个抽屉里,只靠数据库字段标记归属,前端一绕过权限校验就全裸奔。
- 用户上传时,
upload_to必须动态拼接用户名或 user_id,例如:upload_to='uploads/%(user_id)s/%(filename)s',且需在 Model 字段中用 callable 实现,不能写死字符串 -
settings.py中的MEDIA_ROOT只设为根目录(如/var/www/mycloud/media),绝不设成用户可直访的子路径 - Nginx 配置中,
location /media/必须配合alias+internal指令,禁止外部直接访问,所有媒体请求走 Django 的serve视图做权限校验
大文件上传必须绕过 Django 默认表单解析
浏览器提交的 request.FILES 会把整个文件加载进内存或临时磁盘,上传 2GB 文件时,Django 进程极易 OOM 或超时。断点续传不是“锦上添花”,而是生产环境的刚需。
- 前端用
axios或fetch分片上传,每片带chunkIndex、totalChunks、identifier(如文件 hash) - 后端用
request.body直接读取原始二进制流,写入临时分片目录(如/tmp/uploads/{identifier}/),不经过MultiPartParser - 合并逻辑放在最后一片到达时触发,检查所有分片是否存在、顺序是否完整,再用
shutil.copyfileobj拼接,避免内存拷贝 - 务必设置
DATA_UPLOAD_MAX_MEMORY_SIZE = 0和FILE_UPLOAD_MAX_MEMORY_SIZE = 0,禁用 Django 自动内存缓存
分享链接必须绑定时效与权限,不能只靠 token
生成一个随机字符串作为分享 key,然后在数据库里存一条 ShareLink 记录,看似安全,实则漏洞明显:没做访问频次限制、没校验 referer、没区分“预览”和“下载”动作,攻击者拿到链接就能无限刷取。
-
ShareLink模型必须包含expires_at(datetime)、downloadable(bool)、password_hash(可为空)、visit_count(int,默认 0,上限建议设 10) - 访问分享页时,先查库判断是否过期、是否达上限,再比对密码(用
pbkdf2校验,不用明文比对) - 文件下载接口(如
/share/<code>key/download/)必须单独鉴权,不能复用预览页的 session 或 cookie - 静态资源(如 PDF 预览用的
pdf.js)不要放在media/下,应走独立 CDN 或 Nginx alias,避免泄露分享路径结构
真正卡住部署的,从来不是“怎么写上传视图”,而是 Nginx 的 client_max_body_size 设太小、upload_tmp_dir 权限不对、MySQL 的 max_allowed_packet 不够大——这些参数不调,代码写得再漂亮也 500。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











