Django CSRF Tanımlama Bilgisi Ayarlanmadı


86

Bir süredir sorun yaşıyorum, CSRF Çerezi ayarlanmadı yaşıyorum. Lütfen aşağıdaki kodlara bakın

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'de kod burada

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>

Sıkıştım, çerezi zaten temizledim, başka bir tarayıcı kullandım ama yine de csrf çerezi ayarlanmamış.


Eğer var mı CsrfViewMiddlewaresizin de MIDDLEWARE_CLASSESayara?
alecxe

{%csrf_token%}Formunuza şablona ekleyin .
Rohan

4
@Rohan zaten orada, soruya bakın.
alecxe

1
Evet, zaten CsrfViewMiddleware'im var ve formumda zaten csrf_token var

Django cors modülünü kullanıyorum ve ReactJS aracılığıyla ona erişiyorum. (Her ikisi de localhost'taydı). Benim de OP ile ilgili bu problemim vardı. Benim credentials: 'include'için POST isteğine eklemenin ve ayrıca django'nun settings.py'sine CORS_ALLOW_CREDENTIALS = Trueeklemenin @csrf_exemptgörünüme eklemeye gerek kalmadan sorunu çözdüğünü fark ettim . Aslında belgelerde ... pypi.org/project/django-cors-headers-multi * Bunun yukarıdaki sorulardan biriyle ilgili olduğunu biliyorum ama henüz yorum yapamam ve umarım bir başkasına zamandan tasarruf etmek istedim beni bulmaya götürdü t
DW

Yanıtlar:


134

Bu CSRF_COOKIE_SECURE = True, ayarlanmışsa ve siteye güvenli olmayan bir şekilde erişiyorsanız veya burada ve buradaCSRF_COOKIE_HTTPONLY = True belirtildiği gibi ayarlanmışsa da meydana gelebilir.


10
Teşekkürler! Aynısı için de geçerli 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
Güvenlik mekanizmasını tamamen devre dışı bırakmak, hatayı düzeltmenin iyi bir yolu değildir.
Guillaume Algis

2
2017'de cookiecutter-django kullanıyorsanız, bu üretimde doğru cevaptır.
André Duarte

1
Meraktan neden böyle?
Patrick Gallagher

3
Bu yanıt "güvenlik mekanizmasını tamamen devre dışı bırakmanızı" önermez, yalnızca CSRF belirtecini kullanamayacağınız tek bir durumda bunu nasıl yapacağınızı söyler. Harici bir istemciye bir POST eylemi sunmam gereken durum bu.
mariotomo

Bu, geliştirme aşamasında, UI'den csrf belirteci sağlayamadığınızda kullandığım TODO türü bir öğedir. Ancak canlı bir uygulama için kesinlikle tavsiye edilmez.
Aman Madan

24

Oturum açmış bir kullanıcı olarak POST istekleri yapmak ve almak için HTML5 Getirme API'sini kullanıyorsanız Forbidden (CSRF cookie not set.), bunun nedeni varsayılan olarak fetchoturum çerezlerini içermemesinden dolayı Django'nun sayfayı yükleyen kişiden farklı bir kullanıcı olduğunuzu düşünmesine neden olabilir. .

credentials: 'include'Getirme seçeneğini ileterek oturum jetonunu dahil edebilirsiniz :

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

o Header () yönteminin ne olduğunu öğrenebilir miyim? bu global javascript yöntemi mi?
Abz Rockers

@AbzRockers: Evet, HeadersHTML5 Fetch API'sinin bir parçası olan global bir javascript arayüzü. developer.mozilla.org/en-US/docs/Web/API/Headers
user85461

13

Gönderen Bu şunları ekleyerek bunu çözebilir ensure_csrf_cookie dekoratör görünümünüze

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

bu yöntem işe yaramazsa. ara yazılımda csrf'yi yorumlamaya çalışacaksınız. ve tekrar test edin.


5

DRF ile çalışırken benzer bir durumla karşılaştım, çözüm urls.py'deki View'a .as_view () yöntemini ekliyordu


Siz de bazı kodlar dahil olursa daha iyi olurdu
Alex Jolig

1
@AlexJolig az önce aynı sorunla karşılaştı, sorun şu ki, .as_view()ApiView'umdan sonra eklemeyi unutmuştum. Böylece kod nasıl görünüyordu: urlpatterns += path('resource', ResourceView)Ve böyle olması gerektiği gibi: urlpatterns += path('resource', ResourceView.as_view())
Alveona

4

DRF kullanıyorsanız, url şablonlarınızın doğru olup olmadığını kontrol edin, belki unuttunuz .as_view():

Böylece benim kodum şöyle görünüyordu:

urlpatterns += path('resource', ResourceView) 

Ve böyle olması gerektiği:

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

1

settings.py içinde kurup kurmadığınızı kontrol etmeye çalışın

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

Şablonda veriler csrf_token ile biçimlendirilir:

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

tüm kodunuz elimde değil, ancak sorunun burada olduğuna inanıyorum: def deposit (request, account_num): def deposit (request) olarak değiştirildi: ve account_num'u geri çağırmanın bir yolunu bulun. şimdi hesap_sayısının bir tablo alanı mı yoksa değişken mi olduğuna bağlı olacaktır.
drabo2005

Bu bir değişken {{account_num}}, ancak bu csrf belirtecini nasıl etkiler?

csrf belirtecinin yalnızca isteğe gönderme yaptığına inanıyorum, bu yüzden buradaki değişkenle ne olduğunu doğrulayamıyor veya işleyemiyor. djangoproject.com adresini kontrol edin, csrf_token hakkında uygun bir yanıt alabilirsiniz.
drabo2005


1

Bu, form eylemini ayarlamadığınızda da oluşur.
Benim için, kod şu olduğunda bu hatayı gösteriyordu:

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

Kodumu şu şekilde düzelttiğimde:

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

hatam kayboldu.


0

Sorun, GETtalepleri uygun şekilde ele almadığınız veya formu almadan verileri doğrudan gönderemediğiniz görünüyor .

Sayfaya ilk eriştiğinizde müşteri istek gönderecek GET, bu durumda uygun formla html göndermelisiniz.

Daha sonra kullanıcı formu doldurur ve POSTform verisi ile talep gönderir .

Görüşünüz şöyle olmalıdır:

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

Chrome çerezlerinin web siteleri için varsayılan seçenekle ayarlandığını kontrol edin. Yerel verilerin ayarlanmasına izin ver (önerilen).


0

Yöntem 1:

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

Yöntem 2:

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

Çünkü render_to_response metodu bazı cevap çerezlerinde sorun yaşayabilir.


0

Daha yeni tanıştım, çözüm çerezleri boşaltmak. SECRET_KEY ile ilgili hata ayıklama sırasında değiştirilebilir.


0

Tarayıcımın önbelleğini temizlemek bu sorunu benim için çözdü. Gerçekleştiğinde başka bir proje üzerinde çalıştıktan sonra django-blog-zinnia öğreticisini yapmak için yerel geliştirme ortamları arasında geçiş yapıyordum. İlk başta, INSTALLED_APPS sırasını öğreticiyle eşleşecek şekilde değiştirmenin buna neden olduğunu düşündüm, ancak bunları geri ayarladım ve önbelleği temizleyene kadar düzeltemedim.


0

Daha önce Django 1.10 kullanıyordum, yani bu problemle karşı karşıyaydım. Şimdi onu Django 1.9'a düşürdüm ve iyi çalışıyor.


1.10.3 kullanarak bu sorunu yaşadım. 1.10.6 sürümüne yükseltme benim için sorunu çözdü.
Mike Darmetko

0

Aynı hatayı aldım, benim durumumda method_decorator ekleyerek yardımcı olur:

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 oturumu arka ucunuzun settings.py içinde doğru şekilde yapılandırıldığından emin olun. O zaman bunu dene,

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

Bu ara yazılımı django sürümünün settings.pyaltına MIDDLEWARE_CLASSESveya MIDDLEWAREbağlı olarak ekleyin

get_token - Bir POST formu için gereken CSRF belirtecini döndürür. Belirteç, alfanümerik bir değerdir. Önceden ayarlanmadıysa yeni bir belirteç oluşturulur.


-4

Size göre csrf dekoratör kullanıyor musunuz?

from django.views.decorators.csrf import csrf_protect

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.