从令牌创建Django会话

Jam*_*ell 10 django session nginx angularjs django-rest-framework

问题

我目前正在努力解决从Django提供身份验证强制媒体文件的众所周知的问题.问题的背景很简单:

  • 我们想要使用Django的媒体文件支持
  • 默认情况下,媒体文件不是私有的.事实上,通常网络服务器直接为他们服务.
  • 我们希望在访问媒体文件时对用户进行身份验证
  • 我们在前端使用令牌认证
  • 由于没有有效的会话,浏览器在访问私有文件时无法进行身份验证(例如在新选项卡中打开PDF)
  • 我们希望Django为浏览器提供身份验证,但需要以某种方式使用现有的身份验证令牌进行身份验证
  • 我们仍然希望nginx将文件发回,因此我们将利用X-Accel-Redirect后验证.

试图解决

到目前为止我所做的(并且它可以工作)是创建另一个需要令牌认证的API视图并将文件发回,然后创建一个Angular指令以用blob替换所有受保护的URL.当用户单击链接时,它使用令牌身份验证获取文件,然后创建包含该数据的Blob.然后浏览器打开该blob.

遗憾的是,无法共享blob,因此用户无法为这些文件粘贴彼此的链接.我想知道是否有办法绕过它.

目标

我的目标是使用令牌创建有效(和短期到期)会话.这样,当用户单击链接时,发送请求以检查是否存在有效会话,然后以某种方式配置浏览器以使其可以使用该会话.整个过程看起来像这样:

  • 用户点击链接(实际上是一个更复杂的角度指令)
  • Angular fires请求与服务器的会话
  • 服务器响应必要的信息
  • 使用JavaScript配置浏览器会话
  • 强制浏览器打开新建立的会话链接
  • 根据会话验证用户,使用header将文件发送到nginx

我不是在寻找一个已经实现的答案,我可以自己处理好的细节.我更感兴趣的是获得有关如何以最佳方式完成此操作的反馈.即:

  • 如何在API响应中给出一些会话信息来配置浏览器?
  • 我应该如何处理这些会话到期以使其安全
  • 我该如何建立这个会话?每次点击链接时检查/创建会话是否合理(假设流量不是问题)
  • 这是一个合理的跨浏览器解决方案吗?有更好的方法吗?
  • 当文件URL与没有会话但具有有效令牌的用户共享时,如何使用中间页面来建立此会话?

一些选项

更新:我和一些提出以下选择的同事交谈过:

  • 让API检索单个使用或短期到期令牌而不是会话,并将其作为查询参数附加到文件的URL.在请求中验证这一点.这有效,但仍然不允许共享URL.
  • 登录时建立会话.如果用户尝试访问文件时该会话已过期,则重定向到会话登录,然后在进行身份验证时重定向回文件.这也有效,但我想避免额外的身份验证步骤,因为令牌有很长的到期时间,会话有一个很短的时间.赋予它们相同的到期也会有缺点,因为更频繁到期的令牌或经常过期的会话并不理想.

C14*_*14L 4

您可以简单地将令牌放入 cookie 中。

这样,浏览器就会自动将其发送到服务器,当用户直接访问可下载文件时,您可以使用它进行身份验证。

告诉Authorization:Django 中间件从 cookie 中读取令牌字符串,而不是读取标头。