使用 AJAX、CSRF 和 CORS

“仔细查看您自己的网站上可能的 CSRF/XSRF 漏洞。它们是最糟糕的漏洞类型——攻击者很容易利用,但对于软件开发人员来说却不容易理解,至少在您被咬一口之前是这样。”

杰夫·阿特伍德

Javascript 客户端

如果您正在构建一个 JavaScript 客户端与您的 Web API 交互,您需要考虑客户端是否可以使用网站其他部分使用的相同身份验证策略,还要确定您是否需要使用 CSRF 令牌或 CORS 头。

在与它们交互的 API 的上下文中发出的 AJAX 请求通常会使用 SessionAuthentication。这确保在用户登录后,可以使用与网站其他部分相同的基于会话的身份验证对发出的任何 AJAX 请求进行身份验证。

在与它们通信的 API 所在的不同站点上发出的 AJAX 请求通常需要使用非基于会话的身份验证方案,例如 TokenAuthentication

CSRF 保护

跨站请求伪造保护是一种针对特定类型攻击的防护机制,这种攻击可能发生在用户未注销网站并继续拥有有效会话时。在这种情况下,恶意网站可能能够在已登录会话的上下文中对目标网站执行操作。

要防止此类攻击,您需要做两件事

  1. 确保无法使用“安全”HTTP 操作(例如 GETHEADOPTIONS)来更改任何服务器端状态。
  2. 确保任何“不安全”HTTP 操作(例如 POSTPUTPATCHDELETE)始终需要有效的 CSRF 令牌。

如果您使用的是 SessionAuthentication,则需要为任何 POSTPUTPATCHDELETE 操作包含有效的 CSRF 令牌。

为了发出 AJAX 请求,您需要在 HTTP 头中包含 CSRF 令牌,如 Django 文档中所述

CORS

跨域资源共享是一种允许客户端与托管在不同域上的 API 交互的机制。CORS 的工作原理是要求服务器包含一组特定的头,以便浏览器确定是否以及何时应允许跨域请求。

在 REST 框架中处理 CORS 的最佳方法是在中间件中添加所需的响应头。这确保了透明地支持 CORS,而无需更改视图中的任何行为。

Adam Johnson 维护 django-cors-headers 包,该包已知可以与 REST 框架 API 正确配合使用。