Файл cookie Django CSRF не встановлено


85

Я маю певну проблему вже деякий час, я відчуваю файл cookie CSRF не встановлений. Будь ласка, подивіться на коди нижче

Python

def deposit(request,account_num):
if request.method == 'POST':
    account = get_object_or_404(account_info,acct_number=account_num)
    form_=AccountForm(request.POST or None, instance=account)
    form = BalanceForm(request.POST)
    info = str(account_info.objects.filter(acct_number=account_num))
    inf=info.split()
    if form.is_valid():
    #cd=form.cleaned_data
        now = datetime.datetime.now()
        cmodel = form.save()
        cmodel.acct_number=account_num
        #RepresentsInt(cmodel.acct_number)
        cmodel.bal_change="%0.2f" % float(cmodel.bal_change)
        cmodel.total_balance="%0.2f" %(float(inf[1]) + float(cmodel.bal_change))
        account.balance="%0.2f" % float(cmodel.total_balance)
        cmodel.total_balance="%0.2f" % float(cmodel.total_balance)
        #cmodel.bal_change=cmodel.bal_change
        cmodel.issued=now.strftime("%m/%d/%y %I:%M:%S %p")
        account.recent_change=cmodel.issued
        cmodel.save()
        account.save()
        return HttpResponseRedirect("/history/" + account_num + "/")
    else:
        return render_to_response('history.html',
                          {'account_form': form},
                          context_instance=RequestContext(request))

У HTML ось код

HTML

<form action="/deposit/{{ account_num }}/" method="post">

<table>
<tr>
{{ account_form.bal_change }}
&nbsp;
<input type="submit" value="Deposit" />
</tr>
{% csrf_token %}
</table>
</form>

Я застряг, я вже очистив файл cookie, використовував інший браузер, але файл cookie csrf все ще не встановлений.


Ви маєте CsrfViewMiddlewareу своєму MIDDLEWARE_CLASSESналаштуванні?
alecxe

Додайте {%csrf_token%}форму у шаблон.
Рохан,

4
@Rohan це вже є, дивіться питання.
alecxe

1
Так, у мене вже є CsrfViewMiddleware, і я вже маю csrf_token у своїй формі

Я використовував модуль Django cors і отримував до нього доступ через ReactJS. (Обидва були на localhost). У мене також була така проблема ОП. Я виявив для мене, що додавання credentials: 'include'до запиту POST, а потім ТАКЖЕ додавання у налаштуваннях django's settings.py: CORS_ALLOW_CREDENTIALS = Trueздається, вирішило проблему без необхідності додавання @csrf_exemptдо подання. Це насправді в документах ... pypi.org/project/django-cors-headers-multi * Я знаю, що це пов’язано з одним із запитань вище, але я поки що не можу коментувати і, сподіваюся, заощадив комусь іншому час взяв мене знайти t
DW

Відповіді:


134

Це також може статися, якщо CSRF_COOKIE_SECURE = Trueвстановлено, і ви заходите на сайт ненадійно, або якщо CSRF_COOKIE_HTTPONLY = Trueвстановлено, як зазначено тут і тут


10
Дякую! Те саме стосується SESSION_COOKIE_SECURE = True.
NonameSL

74
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt 
def your_view(request):
    if request.method == "POST":
        # do something
    return HttpResponse("Your response")

60
Повне відключення механізму безпеки - це не найкращий спосіб виправити помилку.
Гійом Альгіс

2
Якщо ви використовуєте cookiecutter-django у 2017 році, це правильна відповідь у виробництві.
Андре Дуарте,

1
Чому це з цікавості?
Патрік Галлахер,

3
Ця відповідь не пропонує "повністю вимкнути механізм безпеки", вона лише розповідає, як це зробити для одного випадку, коли ви не можете використовувати маркер CSRF. Це мій випадок, коли мені потрібно запропонувати дію POST зовнішньому клієнту.
mariotomo

Це елемент типу TODO, який я використовую на етапі розробки, коли ви не можете надати маркер csrf з інтерфейсу користувача. Але, звичайно, не рекомендується для живого додатка.
Аман Мадан

24

Якщо ви використовуєте API вибору HTML5 для надсилання запитів POST як зареєстрованого користувача та отримання Forbidden (CSRF cookie not set.), це може бути тому, що за замовчуванням fetchне включає файли cookie сеансу, в результаті чого Django думає, що ви інший користувач, ніж той, хто завантажив сторінку .

Ви можете включити маркер сеансу, передавши опцію credentials: 'include'отримання:

var csrftoken = getCookie('csrftoken');
var headers = new Headers();
headers.append('X-CSRFToken', csrftoken);
fetch('/api/upload', {
    method: 'POST',
    body: payload,
    headers: headers,
    credentials: 'include'
})

Чи можу я знати, що це за метод Header (), який ви створили? це глобальний метод javascript?
Abz Rockers

@AbzRockers: Так, Headersце глобальний інтерфейс javascript, частина API HTML5 Fetch. developer.mozilla.org/en-US/docs/Web/API/Headers
user85461

13

З цього Ви можете вирішити це, додавши до свого подання декоратор secure_csrf_cookie

from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def yourView(request):
 #...

якщо цей метод не працює. ви спробуєте прокоментувати csrf у проміжному програмному забезпеченні. і перевірити ще раз.


5

Я зіткнувся з подібною ситуацією під час роботи з DRF, рішення додало метод .as_view () до подання в urls.py


Було б краще, якби ви також включили якийсь код
Алекс Джоліг,

1
@AlexJolig щойно зіткнувся з тією ж проблемою, проблема полягала в тому, що я забув додати .as_view()після мого ApiView, щоб так виглядав код: urlpatterns += path('resource', ResourceView)І ось як він повинен сподобатися: urlpatterns += path('resource', ResourceView.as_view())
Alveona

4

Якщо ви використовуєте DRF, перевірте, чи правильні ваші шаблони URL, можливо, ви забули .as_view():

Отже, як виглядав мій код:

urlpatterns += path('resource', ResourceView) 

І ось як це має сподобатися:

urlpatterns += path('resource', ResourceView.as_view())

1

спробуйте перевірити, чи встановлено вашу програму в settings.py

 MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',)

У шаблоні дані відформатовані за допомогою csrf_token:

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

у мене немає всього вашого коду, але я вважаю, що справа тут: def deposit (request, account_num): змінив його на def deposit (request): і знайшов спосіб зворотного виклику account_num. тепер це буде залежати від того, чи є account_num полем таблиці або змінною.
drabo2005

Це змінна {{account_num}}, але як це впливає на маркер csrf?

Я вважаю, що маркер csrf посилався лише на запит, тому він не може перевірити або обробити те, що відбувається зі змінною тут. перевірте djangoproject.com, можливо, ви могли б отримати правильну відповідь про csrf_token.
drabo2005

1

Ця проблема знову виникла нещодавно через помилку в самому Python.

http://bugs.python.org/issue22931

https://code.djangoproject.com/ticket/24280

Серед порушених версій були 2.7.8 та 2.7.9. Файл cookie було прочитано неправильно, якщо одне зі значень містило [символ.

Оновлення Python (2.7.10) вирішує проблему.


1

Це також відбувається, коли ви не встановите дію форми.
Для мене він показував цю помилку, коли код був:

<form class="navbar-form form-inline my-2 my-lg-0" role="search" method="post">

Коли я виправив свій код на це:

<form class="navbar-form form-inline my-2 my-lg-0" action="{% url 'someurl' %}" role="search" method="post">

моя помилка зникла.


0

Проблема, схоже, полягає в тому, що ви не обробляєте GETзапити належним чином або не публікуєте дані безпосередньо, не отримавши попередньо форму.

Коли ви вперше заходите на сторінку, клієнт надішле GETзапит, у цьому випадку ви повинні надіслати html із відповідною формою.

Пізніше користувач заповнює форму та надсилає POSTзапит із даними форми.

Ваш погляд повинен бути таким:

def deposit(request,account_num):
   if request.method == 'POST':
      form_=AccountForm(request.POST or None, instance=account)
      if form.is_valid(): 
          #handle form data
          return HttpResponseRedirect("/history/" + account_num + "/")
      else:
         #handle when form not valid
    else:
       #handle when request is GET (or not POST)
       form_=AccountForm(instance=account)

    return render_to_response('history.html',
                          {'account_form': form},
                          context_instance=RequestContext(request))

0

Переконайтеся, що файли cookie chrome встановлені за замовчуванням для веб-сайтів. Дозволити встановлення локальних даних (рекомендується).


0

Спосіб 1:

from django.shortcuts import render_to_response
return render_to_response(
    'history.html',
    RequestContext(request, {
        'account_form': form,
    })

Спосіб 2:

from django.shortcuts import render
return render(request, 'history.html', {
    'account_form': form,
})

Оскільки метод render_to_response може спричинити певну проблему з файлами cookie відповіді.


0

Я щойно зустрівся, рішення полягає в тому, щоб очистити файли cookie. І може бути змінений під час налагодження, пов’язаного з SECRET_KEY.


0

Очищення кешу браузера вирішило цю проблему для мене. Я перемикався між локальними середовищами розробки, щоб робити підручник django-blog-zinnia після роботи над іншим проектом, коли це сталося. Спочатку я думав, що зміна порядку INSTALLED_APPS відповідно до навчального посібника спричинило це, але я повернув їх назад і не зміг це виправити, поки не очистив кеш.


0

Я раніше використовував Django 1.10, тому стикався з цією проблемою. Зараз я знизив його до Django 1.9, і він працює нормально.


Використовуючи 1.10.3, у мене виникла ця проблема. Оновлення до 1.10.6 виправило це для мене.
Mike Darmetko

0

У мене була та ж помилка, у моєму випадку додавання method_decorator допомагає:

from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator

method_decorator(csrf_protect)
def post(self, request):
    ...

0

Переконайтеся, що ваш серверний сервер django налаштований належним чином у settings.py. Тоді спробуйте це,

class CustomMiddleware(object):
  def process_request(self,request:HttpRequest):
      get_token(request)

Додайте це проміжне програмне забезпечення в settings.pyUnder MIDDLEWARE_CLASSESабо в MIDDLEWAREзалежності від версії Джанго

get_token - Повертає маркер CSRF, необхідний для форми POST. Маркер є буквено-цифровим значенням. Створюється новий маркер, якщо він ще не встановлений.


-4

На ваш погляд, ви використовуєте декоратор csrf ??

from django.views.decorators.csrf import csrf_protect

@csrf_protect def view(request, params): ....

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.