Джанго: POST-форма требует CSRF?ПОЛУЧИТЬ не? - PullRequest
5 голосов
/ 26 августа 2010

Требуются ли формы, использующие метод POST, для защиты от CSRF? Я слежу за книгой, и примеры кода выдают 403 ошибки. Я провел поиск, и мне кажется, что мне нужно включить CSRF во всех моих формах.

Мои вопросы:

  1. Требует ли теперь Django, чтобы все формы POST были защищены от CSRF?

  2. Все, что мне нужно для этого сделать, это добавить 'django.middleware.csrf.CsrfViewMiddleware', вернуть render_to_response (шаблон, словарь, context_instance = RequestContext (request) и добавить '{% csrf_token%}' в соответствующая форма? Я что-то здесь упускаю?

Когда я делаю это, форма работает нормально. Когда какая-либо из этих частей отсутствует, она не достигает 403. Я просто хочу убедиться, что я делаю это правильно. :)

Заранее спасибо.

редактирование:

По какой-то причине этот код не имеет смысла для меня, но он не возвращает никакой ошибки. Пожалуйста, игнорируйте примитивную проверку, так как я еще не попал в раздел книги, где он показывает более эффективный способ сделать это.

def contact(request):
    errors = []

    if request.method == 'POST':
        if not request.POST.get('subject',''):
            errors.append('Enter a subject')
        if not request.POST.get('message',''):
            errors.append('Enter a message')
        if request.POST.get('email', '') and '@' not in request.POST['email']:
            errors.append('Enter a valid email address')
        if not errors:
            send_mail(
                request.POST['subject'],
                request.POST['message'],
                request.POST.get('email', 'noreply@example.com'), ['siteownder@example.com'],)
            return HttpResponseRedirect('/contact/thanks/')

    return render_to_response('contact_form.html', { 'errors': errors }, context_instance=RequestContext(request))

Моя проблема связана с самой последней строкой этой функции просмотра. Он вызывается только если request.method! = POST. Это кажется мне совершенно неправильным. Разве я не должен вызывать context_instance = RequestContext (request), когда он выполняет POST?

1 Ответ

8 голосов
/ 26 августа 2010

POST должен использоваться для конфиденциальной информации, такой как пароли, и django требует защиты с помощью csrf_token; GET следует использовать для закладок, которые не нужно защищать, например, для поиска. Вы делаете это правильно.

EDIT

Вы не должны звонить context_instance=RequestContext(request), когда он делает POST, вы должны вызывать его независимо от типа запроса. Посмотрите на это так:

  • Это POST? это означает, что форма была отправлена. мы проверяем форму и перенаправляем пользователя на другую страницу, если форма в порядке или снова показывает форму пользователю с ошибками .
  • Это GET? это означает, что форма не была отправлена, но происходит другой материал, который нас не волнует (какая-то реферальная ссылка или другой материал). Показать форму в любом случае

Действия, выделенные курсивом, выполняются последним возвратом, независимо от if.

...