跨域请求的 CSRF 免除 Django 身份验证密码重置视图

CSRF Exempt Django Auth Password Reset View for Cross Domain request

我有一个单独的前端和后端站点,我正在尝试让前端的用户重设他们的密码。我已经为他们创建了一个端点,当通过后端站点访问时它可以工作。但是当我尝试通过 Insomnia 访问端点时,我得到:

Forbidden (403)

CSRF verification failed. Request aborted.

我已将我的前端域添加到 CORS_ORIGIN_WHITELIST

class PasswordResetView(auth_views.PasswordResetView):
    template_name = 'users/reset_password.html'

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

我还必须制作其他方法吗csrf_exempt

django.contrib.auth.views.PasswordResetViewcsrf_protect 修饰其 dispatch 方法,其中 csrf_protect = decorator_from_middleware(CsrfViewMiddleware).

用你的 csrf_exempt 和实际的 CsrfViewMiddleware 换行,我们有 csrf_protect(csrf_exempt(csrf_protect(<bound method PasswordResetView.dispatch ...>))),其中 <bound method PasswordResetView.dispatch ...>super().dispatch

可以减少到 csrf_protect(<bound method PasswordResetView.dispatch ...>)

我们可以通过设置 request.csrf_processing_done = True:

来欺骗 CsrfViewMiddleware
class PasswordResetView(auth_views.PasswordResetView):
    template_name = 'users/reset_password.html'

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

或者,您可以设置 super().dispatch.__wrapped__.csrf_exempt = True,但这会影响继承 auth_views.PasswordResetView 的其他视图 类,因为 super().dispatch.__wrapped__ 只是 [=26] =].