【发布时间】:2021-01-11 13:42:20
【问题描述】:
我正在尝试为对匿名用户开放的 Django Rest API 强制执行 CSRF。 为此,我尝试了两种不同的方法:
- 从一个
CSRFAPIView基本视图扩展选定的 API 视图,该基本视图在调度方法上有一个@ensure_csrf_cookie注释。 - 使用基于 SessionAuthentication 的自定义 Authentication 类,无论用户是否登录,它都会应用
enforce_csrf()。
在这两种方法中,CSRF 检查似乎都在表面上起作用。如果 cookie 中缺少 CSRF 令牌或令牌的长度不正确,端点将返回 403 - Forbidden。
但是,如果我在 cookie 中编辑 CSRF 令牌的值,则请求会被毫无问题地接受。所以我可以为 CSRF 使用随机值,只要它的长度正确。
这种行为似乎偏离了常规的 Django 登录视图,其中 CSRF 的内容确实很重要。我正在使用 debug/test_environment 标志在本地设置中进行测试。
我在 DRF 中的自定义 CSRF 检查未得到深入验证的原因可能是什么?
自定义认证的代码片段:
class RestCsrfAuthentication(SessionAuthentication):
def authenticate(self, request):
self.enforce_csrf(request)
rotate_token(request)
return None
在设置中:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'csrfexample.authentication.RestCsrfAuthentication',
]
}
【问题讨论】:
-
快速检查一下:您是否尝试禁用 debug/test_env 标志?
-
我也在非调试环境下试过了。我已经将它与调试模式下的其他 CSRF 行为(登录页面)进行了比较,并且登录页面上的行为更加严格。
-
你能分享这两种方法的实现细节吗? (对于#2,我假设您正在覆盖
SessionAuthentication.authenticate()?)无论使用哪种HTTP 方法,都会发生这种情况吗?你使用的是什么 Django 和 DRF 版本? -
@DJRamones 我正在使用 Django 3.0.10,DRF 3.11.2
标签: django django-rest-framework csrf