Исключение кросс-доменного сброса пароля Django из CSRF токена
У меня есть отдельный внешний и внутренний сайт, и я пытаюсь дать пользователям внешнего сайта возможность сбросить свой пароль. Я создал для них конечную точку, которая работает при доступе через внутренний сайт. Но когда я пытаюсь получить доступ к конечной точке через Insomnia, я получаю сообщение 403 CSRF verification failed. Запрос прерван. ошибка. Я добавил свой front end ddomain в 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.PasswordResetView украшает свой метод dispatch методом csrf_protect, где 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 ...>).
Мы можем обмануть CsrfViewMiddleware, установив request.csrf_processing_done = True:
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__ - это просто <function PasswordResetView.dispatch ...>.