【问题标题】:csrf_exempt not working with django authcsrf_exempt 不适用于 django auth
【发布时间】:2014-01-08 12:21:08
【问题描述】:

我正在为移动应用程序制作后端,并使用带有 Userena 的 Django 进行用户管理。我使用 Django REST 框架登录并注册,一切正常。我现在唯一需要做的就是实现“忘记密码”功能。我想使用 Userena 中已经实现的一个,但即使在使用 csrf_exempt 分离器之后,我也无法摆脱错误“CSRF 令牌丢失或不正确”。我在做什么?

urls.py

from django.contrib.auth.views import password_reset
from django.views.decorators.csrf import csrf_exempt
...
urlpatterns = patterns(
    '',
    url(r'^password/mobile/reset/$',
       csrf_exempt(password_reset),
       {'template_name': 'userena/password_reset_form.html',
        'email_template_name': 'userena/emails/password_reset_message.txt',
        'extra_context': {'without_usernames': userena_settings.USERENA_WITHOUT_USERNAMES}
        },
       name='userena_password_mobile_reset'),
)

passowrd_reset_form.html

{% extends 'userena/base_userena.html' %}
{% load i18n %}

{% block title %}{% trans "Reset password" %}{% endblock %}

{% block content %}
<form action="" method="post">
  <fieldset>
    <legend>{% trans "Reset Password" %}</legend>
    {% csrf_token %}
    {{ form.as_p }}
  </fieldset>
  <input type="submit" value="{% trans "Send password" %}" />
</form>
{% endblock %}

【问题讨论】:

  • 如果您查看该表单发送的请求,例如在浏览器的开发工具(“网络”选项卡...)中,CSRF 令牌是否包含在发送的数据中?从 CSRF 保护中排除视图不是一个好主意,因为它允许攻击者重置用户的密码
  • 你也可以添加views.py 只是想检查csrf_exempt 装饰器。
  • @sawangupta csrf_excempt 应用在他的 url 配置中,csrf_exempt(password_reset)
  • @sk1p 当我使用浏览器时一切正常,因为包含 CSRF 令牌。当我尝试使用移动应用程序(直接 POST 请求)或使用 curl 时,它会中断,因为在这些应用程序中我不包含 CSRF 令牌。我的问题是如何禁用 django 向我询问 CSRF 令牌。我知道这样做会带来安全隐患。

标签: django django-rest-framework django-csrf csrf-protection


【解决方案1】:

如果您在 POST 到密码重置视图之前执行 GET 请求,您会在 cookie 中获得 CSRF 令牌,然后您可以将其发送到您的 POST 请求中。

如果你坚持豁免视图:我认为问题在于 CSRF 保护应用于password_reset 视图的方式。它由csrf_protect 明确修饰。

要仔细查看问题,假设original_password_reset_viewpassword_reset,没有csrf_protect。基本上,你正在这样做:

csrf_exempt(csrf_protect(original_password_reset_view))
# ^^ your code
#           ^^ the decorator in django.contrib.auth.views

加上CsrfViewMiddleware的效果,我们得到等价于

csrf_protect(csrf_exempt(csrf_protect(original_password_reset_view)))

csrf_protect 只是来自CsrfViewMiddlewaremiddleware-turned-decoratorcsrf_exempt 在另一方面 simply sets csrf_exempt=True 在它的论点上。因此,由外部csrf_protect 表示的中间件在视图上看到csrf_exempt=True 值并禁用其CSRF 投影。它否定了 外部 csrf_protect。所以我们有:

csrf_protect(original_password_reset_view)

视图仍然受到保护。基本上,没有理智的方法。 (一种疯狂的方法:编写一个为该特定 URL 设置 request.csrf_processing_done = True 的中间件。不要那样做......)

【讨论】:

  • 感谢您的解释!
猜你喜欢
  • 1970-01-01
  • 2015-02-03
  • 2015-09-03
  • 2016-11-06
  • 1970-01-01
  • 1970-01-01
  • 2022-06-29
  • 2021-06-27
相关资源
最近更新 更多