Plik cookie Django CSRF nie jest ustawiony


85

Mam jakiś problem od jakiegoś czasu, doświadczam CSRF Cookie nie jest ustawiony. Proszę spojrzeć na poniższe kody

Pyton

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))

W kodzie HTML jest kod

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>

Utknąłem, wyczyściłem już plik cookie, użyłem innej przeglądarki, ale nadal nie ustawiłem pliku cookie csrf.


Czy masz CsrfViewMiddlewarew swoim MIDDLEWARE_CLASSESotoczeniu?
alecxe

Dodaj {%csrf_token%}swój formularz w szablonie.
Rohan

4
@Rohan już tam jest, zobacz pytanie.
alecxe

1
Tak, mam już CsrfViewMiddleware i mam już csrf_token w swoim formularzu

Korzystałem z modułu Django cors i uzyskiwałem do niego dostęp przez ReactJS. (Oba znajdowały się na hoście lokalnym). Miałem też ten problem z OP. Znalazłem dla mnie, że dodanie credentials: 'include'do żądania POST, a następnie dodanie RÓWNIEŻ w settings.py django: CORS_ALLOW_CREDENTIALS = Truewydaje się, że rozwiązało problem bez konieczności dodawania @csrf_exemptdo widoku. Właściwie to jest w dokumentach ... pypi.org/project/django-cors-headers-multi * Wiem, że dotyczy to jednego z powyższych pytań, ale nie mogę jeszcze komentować i mam nadzieję, że chcę zaoszczędzić komuś innemu czas zabrał mnie do znalezienia t
DW

Odpowiedzi:


134

Może się to również zdarzyć, jeśli CSRF_COOKIE_SECURE = Truejest ustawione i uzyskujesz dostęp do witryny w sposób niezabezpieczony lub jeśli CSRF_COOKIE_HTTPONLY = Truejest ustawione tak, jak podano tutaj i tutaj


10
Dzięki! To samo dotyczy 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
Całkowite wyłączenie mechanizmu zabezpieczeń nie jest dobrym sposobem na naprawienie błędu.
Guillaume Algis

2
Jeśli używasz cookiecutter-django w 2017 roku, jest to poprawna odpowiedź w produkcji.
André Duarte

1
Dlaczego z ciekawości?
Patrick Gallagher

3
Ta odpowiedź nie sugeruje „całkowitego wyłączenia mechanizmu bezpieczeństwa”, a jedynie mówi, jak to zrobić w pojedynczym przypadku, w którym możesz nie być w stanie użyć tokenu CSRF. To jest mój przypadek, w którym muszę zaoferować akcję POST klientowi zewnętrznemu.
mariotomo

Jest to element typu TODO, którego używam w fazie rozwoju, kiedy nie możesz dostarczyć tokenu csrf z interfejsu użytkownika. Ale z pewnością nie jest to zalecane w przypadku aplikacji na żywo.
Aman Madan

24

Jeśli używasz interfejsu API pobierania HTML5 do wysyłania żądań POST jako zalogowany użytkownik i otrzymujesz Forbidden (CSRF cookie not set.), może to być spowodowane tym , że domyślnie fetchnie zawiera plików cookie sesji, co powoduje, że Django myśli, że jesteś innym użytkownikiem niż ten, który załadował stronę .

Możesz dołączyć token sesji, przekazując opcję credentials: 'include'pobierania:

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

czy mogę wiedzieć, jaka jest ta metoda Header (), którą utworzyłeś? czy to globalna metoda javascript?
Abz Rockers

@AbzRockers: Tak, Headersto globalny interfejs javascript, część HTML5 Fetch API. developer.mozilla.org/en-US/docs/Web/API/Headers
user85461

13

Z tego Możesz go rozwiązać, dodając dekorator sure_csrf_cookie do swojego widoku

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

jeśli ta metoda nie działa. spróbujesz skomentować csrf w oprogramowaniu pośrednim. i przetestuj ponownie.


5

Podobną sytuację natknąłem się podczas pracy z DRF, rozwiązaniem było dodanie metody .as_view () do widoku w urls.py


Byłoby lepiej, gdybyś dołączył również jakiś kod
Alex Jolig

1
@AlexJolig właśnie zmierzył się z tym samym problemem, problem polegał na tym, że zapomniałem dodać .as_view()później mojego ApiView, więc kod wyglądał tak: urlpatterns += path('resource', ResourceView)I tak powinno wyglądać: urlpatterns += path('resource', ResourceView.as_view())
Alveona

4

Jeśli używasz DRF, sprawdź, czy twoje wzorce url są poprawne, być może zapomniałeś .as_view():

A więc jak wyglądał mój kod:

urlpatterns += path('resource', ResourceView) 

I tak powinno być:

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

1

spróbuj sprawdzić, czy masz zainstalowane w settings.py

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

W szablonie dane są formatowane za pomocą csrf_token:

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

nie mam całego twojego kodu, ale wydaje mi się, że sprawa jest tutaj: def deposit (request, account_num): zmieniono go na def deposit (request): i znajdź sposób na oddzwonienie do account_num. teraz będzie zależeć, czy account_num jest polem tabeli, czy zmienną.
drabo2005

To jest zmienna {{account_num}}, ale jak to wpływa na token csrf?

Uważam, że token csrf odnosił się tylko do żądania, więc nie może zweryfikować ani obsłużyć tego, co dzieje się ze zmienną tutaj. sprawdź djangoproject.com może być, że możesz uzyskać poprawną odpowiedź na temat csrf_token.
drabo2005


1

Dzieje się tak również wtedy, gdy nie ustawisz akcji formularza.
U mnie pokazywał ten błąd, gdy kod był:

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

Kiedy poprawiłem mój kod w ten sposób:

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

mój błąd zniknął.


0

Wygląda na to, że nie obsługujesz GETprawidłowo wniosków lub nie przesyłasz bezpośrednio danych bez uprzedniego uzyskania formularza.

Przy pierwszym wejściu na stronę klient wyśle GETzapytanie, w takim przypadku należy wysłać html z odpowiednim formularzem.

Później użytkownik wypełnia formularz i wysyła POST zapytanie z danymi formularza.

Twój pogląd powinien wyglądać następująco:

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

Sprawdź, czy pliki cookie Chrome są ustawione z domyślną opcją dla witryn internetowych. Zezwalaj na ustawianie danych lokalnych (zalecane).


0

Metoda 1:

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

Metoda 2:

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

Ponieważ metoda render_to_response może powodować problem z plikami cookie odpowiedzi.


0

Spotkałem się tylko raz, rozwiązaniem jest opróżnienie ciasteczek. I może zostać zmieniony podczas debugowania związanego z SECRET_KEY.


0

Wyczyszczenie pamięci podręcznej przeglądarki rozwiązało ten problem. Przełączałem się między lokalnymi środowiskami programistycznymi, aby wykonać samouczek django-blog-zinnia po pracy nad innym projektem, kiedy to się stało. Na początku myślałem, że zmiana kolejności INSTALLED_APPS w celu dopasowania do samouczka spowodowała to, ale ustawiłem je z powrotem i nie mogłem tego poprawić, dopóki nie wyczyściłem pamięci podręcznej.


0

Wcześniej używałem Django 1.10, więc miałem ten problem. Teraz obniżyłem go do Django 1.9 i działa dobrze.


Używając 1.10.3 miałem ten problem. Aktualizacja do wersji 1.10.6 rozwiązała problem.
Mike Darmetko

0

Miałem ten sam błąd, w moim przypadku dodanie method_decorator pomaga:

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

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

0

Upewnij się, że backend sesji django jest poprawnie skonfigurowany w settings.py. Następnie spróbuj tego,

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

Dodaj to oprogramowanie pośrednie settings.pypod MIDDLEWARE_CLASSESlub w MIDDLEWAREzależności od wersji django

get_token - zwraca token CSRF wymagany dla formularza POST. Token jest wartością alfanumeryczną. Nowy token jest tworzony, jeśli nie został jeszcze ustawiony.


-4

Czy Twoim zdaniem używasz dekoratora CSRF?

from django.views.decorators.csrf import csrf_protect

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.