Cookie Django CSRF non impostato


86

Ho qualche problema da un po 'di tempo, sto riscontrando che il cookie CSRF non è impostato. Si prega di guardare i codici di seguito

Pitone

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

Nell'HTML ecco il codice

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>

Sono bloccato, ho già cancellato il cookie, utilizzato un altro browser ma il cookie csrf non è ancora impostato.


Hai CsrfViewMiddlewarenel tuo MIDDLEWARE_CLASSESambiente?
alecxe

Aggiungi il {%csrf_token%}tuo modulo nel modello.
Rohan

4
@Rohan è già lì, guarda la domanda.
alecxe

1
Sì, ho già CsrfViewMiddleware e ho già csrf_token nel mio modulo

Sto usando il modulo Django cors e vi accedo tramite ReactJS. (Entrambi erano su localhost). Ho anche avuto questo problema con l'OP. Ho scoperto per me che l'aggiunta credentials: 'include'alla richiesta POST e quindi l'aggiunta ANCHE nel settings.py di django: CORS_ALLOW_CREDENTIALS = Truesembra aver risolto il problema senza la necessità di aggiungere @csrf_exemptalla vista. In realtà è nei documenti ... pypi.org/project/django-cors-headers-multi * So che si riferisce a una delle domande sopra ma non posso ancora commentare e speriamo di salvare qualcun altro il tempo mi ha portato a trovare t
DW

Risposte:


134

Ciò può verificarsi anche se CSRF_COOKIE_SECURE = Trueè impostato e si accede al sito in modo non sicuro o se CSRF_COOKIE_HTTPONLY = Trueè impostato come indicato qui e qui


10
Grazie! Lo stesso vale per 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")

61
Disattivare completamente il meccanismo di sicurezza non è un buon modo per correggere l'errore.
Guillaume Algis

2
Se stai usando cookiecutter-django nel 2017 questa è la risposta corretta in produzione.
André Duarte

1
Perché per curiosità?
Patrick Gallagher

3
Questa risposta non suggerisce di "disabilitare completamente il meccanismo di sicurezza", spiega solo come farlo per un singolo caso in cui potresti non essere in grado di utilizzare il token CSRF. Questo è il mio caso, in cui devo offrire un'azione POST a un client esterno.
mariotomo

Questo è un tipo di elemento TODO che utilizzo durante la fase di sviluppo, quando non è possibile fornire token csrf dall'interfaccia utente. Ma certamente non consigliato per un'app live.
Aman Madan

24

Se stai utilizzando l' API Fetch HTML5 per effettuare richieste POST come utente registrato e ottenere Forbidden (CSRF cookie not set.), potrebbe essere perché per impostazione predefinita fetchnon include i cookie di sessione, facendo pensare a Django che sei un utente diverso da quello che ha caricato la pagina .

Puoi includere il token di sessione passando l'opzione credentials: 'include'per recuperare:

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

posso sapere qual è il metodo Header () che hai istanziato? è quel metodo javascript globale?
Abz Rockers

@AbzRockers: Sì, Headersè un'interfaccia javascript globale, parte dell'API Fetch HTML5. developer.mozilla.org/en-US/docs/Web/API/Headers
user85461

13

Da questo Puoi risolverlo aggiungendo il decoratore sure_csrf_cookie alla tua vista

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

se questo metodo non funziona. proverai a commentare csrf nel middleware. e prova di nuovo.


5

Mi sono imbattuto in una situazione simile mentre lavoravo con DRF, la soluzione era l'aggiunta del metodo .as_view () alla vista in urls.py


Sarebbe meglio se includessi anche del codice
Alex Jolig

1
@AlexJolig ha appena affrontato lo stesso problema, il problema era che ho dimenticato di aggiungere dopo il .as_view()mio ApiView In modo che l'aspetto del codice: urlpatterns += path('resource', ResourceView)Ed è così che dovrebbe essere: urlpatterns += path('resource', ResourceView.as_view())
Alveona

4

Se stai usando DRF, controlla se i tuoi schemi URL sono corretti, forse ti sei dimenticato .as_view():

Quindi come appariva il mio codice:

urlpatterns += path('resource', ResourceView) 

Ed è così che dovrebbe essere:

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

1

prova a controllare se hai installato nel settings.py

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

Nel modello i dati sono formattati con csrf_token:

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

Non ho tutto il tuo codice ma credo che il problema sia qui: def deposit (request, account_num): cambiato in def deposit (request): e trova un modo per richiamare account_num. ora dipenderà se account_num è un campo della tabella o una variabile.
drabo2005

È una variabile {{account_num}}, ma in che modo influisce sul token csrf?

Credo che il token csrf si riferisse solo alla richiesta, quindi non può verificare o gestire cosa sta succedendo con la variabile qui. controlla djangoproject.com potresti ottenere una risposta corretta su csrf_token.
drabo2005


1

Ciò si verifica anche quando non si imposta l'azione del modulo.
Per me, mostrava questo errore quando il codice era:

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

Quando ho corretto il mio codice in questo:

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

il mio errore è scomparso.


0

Il problema sembra che tu non stia gestendo le GETrichieste in modo appropriato o pubblicando direttamente i dati senza prima ottenere il modulo.

Quando accedi per la prima volta alla pagina, il client invierà la GETrichiesta, in tal caso dovresti inviare html con l'apposito modulo.

Successivamente, l'utente compila il modulo e invia la POSTrichiesta con i dati del modulo.

La tua vista dovrebbe essere:

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

Verifica che i cookie di Chrome siano impostati con l'opzione predefinita per i siti Web. Consenti l'impostazione dei dati locali (consigliato).


0

Metodo 1:

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

Metodo 2:

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

Perché il metodo render_to_response può causare qualche problema con i cookie di risposta.


0

Mi sono appena incontrato una volta, la soluzione è svuotare i biscotti. E può essere modificato durante il debug relativo a SECRET_KEY.


0

La cancellazione della cache del browser ha risolto questo problema per me. Stavo passando da un ambiente di sviluppo locale a un altro per fare il tutorial django-blog-zinnia dopo aver lavorato su un altro progetto quando è successo. All'inizio, pensavo che la causa fosse la modifica dell'ordine di INSTALLED_APPS in modo che corrispondesse al tutorial, ma li ho reimpostati e non sono stato in grado di correggerlo fino a quando non ho svuotato la cache.


0

Prima stavo usando Django 1.10, quindi stavo affrontando questo problema. Ora l'ho declassato a Django 1.9 e funziona bene.


Utilizzando 1.10.3 ho avuto questo problema. L'aggiornamento a 1.10.6 lo ha risolto per me.
Mike Darmetko

0

Ho avuto lo stesso errore, nel mio caso l'aggiunta di method_decorator aiuta:

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

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

0

Assicurati che il backend della tua sessione django sia configurato correttamente in settings.py. Allora prova questo,

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

Aggiungi questo middleware settings.pysotto MIDDLEWARE_CLASSESo in MIDDLEWAREbase alla versione di django

get_token - Restituisce il token CSRF richiesto per un modulo POST. Il token è un valore alfanumerico. Se non è già impostato, viene creato un nuovo token.


-4

Secondo te stai usando il decoratore csrf ??

from django.views.decorators.csrf import csrf_protect

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.