You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何关闭Django auth中PasswordResetView的CSRF校验?

问题解决:Django类视图中@csrf_exempt装饰post方法无效的问题

原因分析

直接在类视图的post方法上添加@csrf_exempt装饰器无法绕过CSRF校验,因为Django的CsrfViewMiddleware会在视图的具体方法(如post)执行之前进行校验,装饰单个方法无法影响中间件的校验流程。

解决方案

有两种可靠的方式可以让类视图跳过CSRF校验:

方案1:在URL配置中装饰as_view()

修改urls.py,将csrf_exempt直接装饰在视图的as_view()方法上:

from django.views.decorators.csrf import csrf_exempt
from . import views

urlpatterns = [
    # 其他URL配置...
    path('reset_password', csrf_exempt(views.ResetPasswordView.as_view()), name='password_reset'),
]

方案2:使用method_decorator装饰类的dispatch方法

dispatch是类视图处理所有请求的入口方法,装饰它可以让整个视图跳过CSRF校验,有两种写法:

写法A:装饰整个类

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.views import PasswordResetView
from django.contrib.messages.views import SuccessMessageMixin

@method_decorator(csrf_exempt, name='dispatch')
class ResetPasswordView(SuccessMessageMixin, PasswordResetView):
    template_name = 'users/password_reset.html'
    email_template_name = 'users/password_reset_email.html'
    subject_template_name = 'users/password_reset_subject'
    success_message = "We've emailed you instructions for setting your password, " \
                      "if an account exists with the email you entered. You should receive them shortly." \
                      " If you don't receive an email, " \
                      "please make sure you've entered the address you registered with, and check your spam folder."
    success_url = reverse_lazy('users-home')

    def post(self, request, *args, **kwargs):
        # 修正:普通Django视图无request.data,需手动解析JSON请求
        import json
        if request.content_type == 'application/json':
            data = json.loads(request.body)
            # 注意你的curl请求发送的是username字段,不是email
            email = data.get('email') or data.get('username')
        else:
            email = request.POST.get('email')
        
        try:
            if User.objects.get(email=email).active:
                print("email: %s " % email)
                return super().post(request, *args, **kwargs)
        except User.DoesNotExist:
            # 捕获特定异常,避免捕获所有异常
            return super().post(request, *args, **kwargs)

写法B:装饰dispatch方法本身

class ResetPasswordView(SuccessMessageMixin, PasswordResetView):
    # 类属性...

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    # post方法...

额外注意事项

  • 你的curl请求发送的是{"username":"abc@dev.com"},但代码中使用request.data.get('email'),而普通Django视图没有request.data属性(这是Django REST Framework视图的特性),需要手动解析JSON请求体,如上文中的代码修正。
  • 避免捕获所有异常(except:),建议捕获User.DoesNotExist,这样不会掩盖其他潜在错误。

内容的提问来源于stack exchange,提问作者Dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 14:35:11