【问题标题】:Django: CSRF check only when certain conditions applyDjango:仅在某些条件适用时才检查 CSRF
【发布时间】:2014-05-31 03:59:16
【问题描述】:

我有一个简单的 REST API,需要从 Web 应用程序和远程服务都可以访问。

远程服务通过包含 API 密钥的自定义 HTTP 标头进行身份验证。

如何保护该 API,使来自 Web 浏览器的请求受到 CSRF 保护,但在通过 API 密钥进行身份验证时未完成 CSRF 检查?或者,一般来说,我如何才能为特定视图上的某些请求启用 CSRF 保护,而不是其他请求?

目前,我有一个装饰器,它检查 API 密钥的请求并大致以这种方式对 API 用户进行身份验证:

# Regular auth
if request.user.is_authenticated():
    # DO CSRF verification, then continue calling the view

elif 'HTTP_X_API_KEY' in request.META:
    api_key = request.META['HTTP_X_API_KEY']
    user = authenticate(username=settings.API_USER_NAME, password=api_key)
    login(request, user)
    # If user is authenticated and autzorized, continue calling the view
    # but WITHOUT invoking CSRF protection

如上所述的问题是,我只想为普通用户提供 CSRF 保护,而不是为 API 用户提供保护。

【问题讨论】:

  • 您可以覆盖 csrf 中间件并在那里进行相同的检查。这样您就不必跟踪需要保护的视图。

标签: django authentication csrf


【解决方案1】:

好的,经过一番修改后,解决方案是禁用 CSRF 中间件并在所有需要 CSRF 保护的情况下启用 csrf_protect

这适用于 API 的特殊情况,因为无论如何每个调用都会被修饰,因此某些视图被遗忘的风险可以忽略不计。

的作用是相反的,使用csrf_exempt。问题是装饰器只在视图上设置了一个csrf_exempt属性,如果你有多个装饰器,即使你使用functools.wraps,它也可能被再次屏蔽。

另外,由于csrf_exempt 在视图上放置了一个属性,它不能根据请求的内容动态启用或禁用 - 这确实是一个非常静态的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    相关资源
    最近更新 更多