如何在Django中加密或混淆REST API URL,生成带有效期的签名文档访问链接
课程签名文档链接及安全方案实现建议
问题1:是否需要改造StudentCourseAck Model存储UUID?
需要,推荐直接新增字段存储UUID,改造复杂度极低,收益更高:
- 新增
access_uuid字段,字段定义参考:
import uuid from django.db import models access_uuid = models.UUIDField( default=uuid.uuid4, unique=True, editable=False, null=True, verbose_name="访问唯一标识" )
- 原有历史记录可以写临时脚本批量生成UUID,新记录创建时会自动生成UUID,不需要额外修改业务代码
- 无需改Model的替代方案:如果不想调整现有表结构,可以直接用Django自带的
django.core.signing模块生成带签名的参数,把学生ID、文档ID加密后作为唯一标识,不需要额外存储,校验时直接解密即可,缺点是无法手动作废/延长单个链接的有效期。
问题2:UUID对应链接的过期控制实现
推荐配合UUID新增过期时间字段,控制逻辑简单易维护:
- 给
StudentCourseAck新增link_expires_atDateTime字段,默认值为空 - 管理员触发发送链接的接口时,将对应记录的
link_expires_at设置为timezone.now() + datetime.timedelta(hours=48) - 唯一链接访问逻辑:
- 取URL中的UUID查询对应
StudentCourseAck记录,查不到直接返回404 - 判断当前时间是否小于
link_expires_at,且签名状态为未签名,否则返回403(链接已过期/已完成签名) - 校验通过后再返回对应文档内容,或者跳转到签名页面
- 取URL中的UUID查询对应
- 如果用前面提到的签名URL替代方案,直接用
signing.dumps的expires_in参数设置48小时有效期,校验时调用signing.loads会自动判断是否过期。
问题3:签名后文档存入学生档案的安全性保障
可通过多层校验规则规避风险:
- 接口权限强校验:签名提交接口必须校验当前登录用户ID和
StudentCourseAck关联的学生ID完全匹配,仅管理员角色可绕过该校验,避免越权提交其他学生的签名 - 幂等控制:已标记为已签名的记录,直接拒绝所有修改签名文档、修改签名状态的请求,避免已确认的文档被恶意篡改
- 完整性校验:签名后的文档生成SHA256哈希值,存在
doc_hash字段中,后续调取档案时比对文件哈希与存储的哈希值,确认文档未被篡改 - 审计留痕:新增操作日志表,记录所有文档生成、签名提交、管理员修改的操作人、操作时间、IP地址,满足教育场景的合规审计要求
- 存储优化建议:不推荐直接在数据库存二进制PDF,可改为存在本地磁盘或者对象存储服务中,数据库仅存文件路径、哈希值,存储成本更低,维护更方便。
内容的提问来源于stack exchange,提问作者DjangoRulz
相关产品推荐
相关产品推荐

