CSRF (Cross-Site Request Forgery) 保护机制。CSRF 攻击是指攻击者通过伪装成用户向应用发送恶意请求,而这些请求是用户在不知情的情况下发起的。例如,如果用户在一个银行网站上登录,然后访问了一个恶意网站,该恶意网站可能包含一个自动提交的表单,这个表单会向银行网站发送请求来转账,因为用户的浏览器会自动附加上之前从银行网站获取的认证信息(如 cookie),所以这个请求会被视为合法的。
为了防止 CSRF 攻击,Django 提供了 CsrfViewMiddleware
中间件,该中间件默认是启用的。它是如何工作的呢?
-
生成 CSRF Token:当用户访问需要 CSRF 保护的页面时(通常是 POST 表单所在的页面),Django 会在响应中设置一个名为
csrftoken
的 cookie,并且在 HTML 表单中插入一个隐藏字段<input type="hidden" name="csrfmiddlewaretoken" value="...">
,其值与 cookie 中的值相同。 -
验证 CSRF Token:当用户提交表单时,Django 会检查请求中的
csrfmiddlewaretoken
字段的值是否与csrftoken
cookie 中的值匹配。只有当两者匹配时,请求才会被认为是有效的,否则将返回一个 HTTP 403 错误。
在 Django 应用中使用 CSRF 保护非常简单:
-
表单中添加 CSRF 令牌:如果你正在创建一个 HTML 表单,确保使用
html 深色版本{% csrf_token %}
模板标签来自动插入 CSRF 令牌。<form method="post"> {% csrf_token %} <!-- 其他表单字段 --> </form>
Django REST Framework (DRF) 主要用于构建 Web API,与传统的 Django 视图相比,API 更多的是面向机器而非直接面向用户的交互。因此,在 DRF 中,默认情况下 CSRF 验证是被禁用的,这是因为:
-
API 设计原则:RESTful API 通常设计为无状态的,这意味着服务器不应该存储任何关于客户端的状态信息。CSRF 保护依赖于 session 或 cookie 来追踪用户状态,这与 REST 的无状态性相冲突。
-
认证机制:DRF 常常使用 token 认证、OAuth2 等更安全的认证机制,这些机制本身就能有效防止未授权的请求。例如,一个 API 客户端在每次请求时都需要提供一个有效的认证 token,这种 token 通常比基于 cookie 的认证更难以被窃取或滥用。
-
使用场景:DRF 构建的 API 通常不是直接由浏览器访问的,而是由移动应用、桌面应用或其他后端服务调用。这些客户端通常不会共享浏览器的 cookie,因此它们不受 CSRF 攻击的影响。
-
灵活性:在某些情况下,你可能确实希望为特定的 API 视图启用 CSRF 保护。DRF 提供了足够的灵活性来实现这一点。你可以通过在视图或视图集中使用
@csrf_protect
装饰器或SessionAuthentication
类来启用 CSRF 保护。
虽然 DRF 默认不启用 CSRF 保护,但这并不意味着在所有情况下都不需要考虑 CSRF 防护。如果你的应用涉及到通过浏览器直接访问的 API 端点(例如,单页应用或传统的 Web 应用),那么你可能需要重新考虑 CSRF 保护。在这种情况下,可以考虑以下方法来增强安全性:
- 启用 SessionAuthentication:在 DRF 的视图或视图集中使用
SessionAuthentication
,这样可以启用 CSRF 保护。 - 自定义认证:根据你的需求自定义认证类,结合使用 token 和 CSRF 保护。
- 教育用户:提醒用户不要在公共计算机上登录敏感应用,并定期更改密码。
总之,DRF 不强制要求 CSRF 保护,但开发者应根据具体的应用场景和安全需求来决定是否以及如何实施 CSRF 保护。
标签:攻击,视图,表单,API,cookie,CSRF,DRF From: https://www.cnblogs.com/clark1990/p/18448739