Постоянный «токен CSRF отсутствует или неверен». Настройка Jinja и Django-регистрации - PullRequest
5 голосов
/ 28 ноября 2010

Я получаю это сообщение:

Маркер CSRF отсутствует или неверен.

На большинстве форумов советуют вам получить {% csrf_token%} в формеи у меня есть.

Также у меня есть в settings.py:

TEMPLATE_CONTEXT_PROCESSORS = (
"django.contrib.auth.context_processors.csrf",
"django.contrib.auth.context_processors.auth",
)

Я использую jinja, который, кажется, не использует CSRF, но затем я установил регистрацию в django, и я потерялся, посколькуКажется, я использую некоторые другие представления, к которым у меня нет доступа, так сказать, они не написаны мной, и я не могу понять, где они находятся."Стандартные виды авторизации", как они их называют.Поэтому я не могу добавить «RequestContext».

Есть идеи, что происходит и как мне это сделать?спасибо

Ответы [ 5 ]

3 голосов
/ 28 ноября 2010

Возможно, вам придется переписать представление регистрации django вручную. Похоже, есть проблема с тем, как Джинджа любит делать вещи и как Django хочет настраивать загрузчики шаблонов. .

Чтобы посмотреть стандартные виды авторизации, просто посмотрите в разделе "site-packages" в вашей установке python.

Вы можете попробовать обернуть стандартные виды аутентификации следующим образом:

from django.contrib.auth.views import login, logout
from django.views.decorators.csrf import csrf_protect

@csrf_protect
def my_wrapped_login_view(request):
    return login(request)

@csrf_protect
def my_wrapped_logout_view(request):
    return logout(request)

Я в основном импортировал стандартные виды авторизации Django и вызвал их с моими собственными, которые имеют украшение csrf_protect. Это стоит того.

2 голосов
/ 04 ноября 2012

Этот ответ не относится только к django-регистрации, но в целом использует Django с Jinja2.

Django CsrfViewMiddleware устанавливает файл cookie csrf_token, если он определяет, что вы получили доступ к члену контекста csrf_token. К сожалению, рендеринг Jinja2 происходит только после выполнения промежуточного программного обеспечения Django. В результате cookie не устанавливается, и поэтому не соответствует форме, и вы получите ошибку 403.

Чтобы обойти эту проблему, вам нужно получить доступ к контексту ['csrf_token'] в какой-то момент, прежде чем вы закончите обработку ответа.

Если вы используете представления на основе классов, вы можете создать CsrfProtectMixin:

class CsrfProtectMixin(object):
    def render_to_response(self, context, **response_kwargs):
        # Csrf processing happens when using a RequestContext. 
        # Be sure to use one.
        if not isinstance(context, RequestContext):
            context = RequestContext(self.request, context)

        # Force access to csrf_token due to the way jinja2 renders the template
        # after middleware has finished processing. Otherwise, the csrf cookie
        # will not be set.
        str(context.get('csrf_token'))

        return super(CsrfProtectMixin, self).render_to_response(context, **response_kwargs)

А потом по вашему мнению класс:

class MyView(CsrfProtectMixin, TemplateView):
    def get(self, request, *args, **kwargs):
        context = {}
        return self.render_to_response(context)

Если вы не используете представления на основе классов, вы можете сделать что-то вроде:

def my_view(request):
    context = RequestContext(request)
    str(context['csrf_token']) #force access to the csrf_token
    return render_to_response('template.html', context)

Или, возможно, патч обезьяны render_to_reponse с логикой в ​​классе выше.

2 голосов
/ 28 ноября 2010

У вас также установлена ​​стандартная система шаблонов Django?Это потребуется для большинства приложений, которые распространяются с шаблонами.

Для CSRF контекстный процессор вставляет переменную 'csrf_token' в контекст ответа, который он извлекает из промежуточного программного обеспечения, если он включен.Теперь все, что вам нужно сделать, это убедиться, что это не ваша форма.

Это прямо из django.core и может быть изменено в любое время.

        if csrf_token:
            if csrf_token == 'NOTPROVIDED':
                return mark_safe(u"")
            else:
                return mark_safe(u"<div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='%s' /></div>" % csrf_token)

Однако, увидев это, все, что вам действительно нужно знать, это то, что у вас должен быть тип ввода csrfmiddlewaretoken со значением context.get ('csrf_token', '') в вашей форме, и это все, что она написала.

1 голос
/ 03 апреля 2011

Самый простой ответ на этот вопрос - просто поместить {% csrf_token%} в тег формы в вашем шаблоне / html.

0 голосов
/ 05 мая 2011

Я просто отключил промежуточное ПО csrf в настройках вот так, и теперь оно работает:

    #'django.middleware.csrf.CsrfViewMiddleware',
...