Запрещенная (403) проверка CSRF не удалась. Запрос прерван

Я делаю приложение формы входа в систему, но когда я запускаю свое приложение и нажимаю кнопку входа в систему, произойдет следующая ошибка

запрещен (403) CSRF для проверки не удалось. Запрос прерван.

код view.py это как:

from django.template import  loader
from django.shortcuts import render_to_response
from registration.models import Registration
from django.http import HttpResponse
from django.template import RequestContext
from django.shortcuts import redirect


def view_login(request,registration_id):
   t = loader.get_template('registration/login.html') 
   try:
         registration=Registration.objects.get(pk=registration_id)
   except Registration.DoesNotExist:
         return render_to_response("login.html",{"registration_id":registration_id})

def home(request,registration_id):
    if request.method == "POST":
      username = request.POST.get('user_name')
      password = request.POST.get('password')
      user = authenticate(username=username, password=password)
      if user is not None:
        if user.is_active:
          login(request, user)
        # success
          return render('registration/main_page.html',{'registration_id':registration_id},context_instance=RequestContext(user))
        else:
         #user was not active
           return redirect('q/',context_instance=RequestContext(user))
      else:
        # not a valid user
           return redirect('q/',context_instance=RequestContext(user))
    else:
       # URL was accessed directly
           return redirect('q/',context_instance=RequestContext(user))

4 ответов


вам нужно добавить {% csrf_token %} в форме

https://docs.djangoproject.com/en/1.4/ref/contrib/csrf/

вот так :

<form>
    {% csrf_token %}
    <anything_else>
</form>

кроме того, вы должны использовать RequestContext(запрос) каждый раз, когда вы используете render_to_response :

return render_to_response("login.html",
    {"registration_id":registration_id},
    context_instance=RequestContext(request))

и вы должны импортировать аутентификацию и логин:

from django.contrib.auth import authenticate, login

я столкнулся с этой проблемой при использовании книги "окончательное руководство по Django", где используется версия 1.1. В книге не рассматривается необходимость проверки csrf_token, которая требуется в более поздних версиях.

чтобы устранить эту проблему, добавьте:

from django.template import RequestContext

к views.py файл и этот добавленный аргумент для функции render_to_response:

context_instance = RequestContext(request)

обязательно добавьте {% csrf_token %} внутри <form> теги в шаблоне


просто комментарий 'django.middleware.csrf.CsrfViewMiddleware'

в вашем settings.py, который работает для меня:

//settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ЭТО МОЖЕТ ИМЕТЬ НЕДОСТАТКИ БЕЗОПАСНОСТИ, ЕСЛИ ВЫ КАК-ТО УПРАВЛЯТЬ CSRF ПО-ДРУГОМУ, И НЕ РЕКОМЕНДУЕТСЯ, ТАК КАК ВЫ БУДЕТЕ ПОДВЕРЖЕНЫ АТАКАМ CSRF


когда вы " запретили (403) проверку CSRF не удалось. Запрос прерван" вы можете альтернативно сделать:

(2) (не рекомендуется)

импорт:

from django.template.context_processors import csrf

добавить в контексте:

context = {}
context.update(csrf(request))

вернуться:

- Django > 1.9 имеет "контекст" вместо "context_instance"

return render_to_response("login.html",
    {"registration_id":registration_id},
    context=context)

(3) (желательно)

импорт:

-вместо импорта "render_to_response" импорт "рендер"

from django.shortcuts import render

вернуться:

return render(request, "login.html", context)

видимо вариант 3 предпочтительнее, потому что "рендер" короче, чем "render_to_response", особенно если вам нужно импортировать и добавить материал. Я мог бы представить, что вариант 2 сохраняет более скудный контекст, но это кажется тривиальным (?).

для ясности:

оба решения по-прежнему нуждаются в {% csrf_token %} в вашей html-форме, как упоминалось выше. И никогда выключите или прокомментируйте csrf middelware.

источники:

старые документы Django 1.9 на RequestContext

Django 2 docs на процессоре csrf

источник, объясняющий рендер, достаточно