2011-08-27 14 views
13

Powiel możliwe:
"CSRF token missing or incorrect" while post parameter via AJAX in DjangoJQuery + AJAX + Django = CSRF?

Chciałem wysłać dane logowania przez AJAX w celu uwierzytelnienia użytkownika, ale nie było to możliwe ze względu na CSRF. Czy możesz mi powiedzieć, co dodać do mojego kodu, aby sprawić, że się odezwał?

mój plik JavaScript:

$("#login").live("click", function() { 
    var username = $(".login_username").val(); 
    var password = $(".login_password").val(); 

    $.ajax({ 
     url: "/login", 
     type: "POST", 
     data: { 
      username: username, 
      password: password 
     }, 
     cache: false, 
     success: function(tekst) { 
      alert(tekst); 
     } 
    }); 
}); 
+0

Wierzę, że możesz znaleźć odpowiedź [tutaj] (https://docs.djangoproject.com/en/dev/ref/contrib/csrf/). Najprostszym rozwiązaniem wydaje się wyłączanie ochrony CSRF w instancji django. Następną najlepszą opcją jest aktualizacja loginu JavaScript, aby pobrać token CSRF Django z formularza i dołączyć go jako część żądania AJAX. – aroth

+1

Spójrz na moją poprzednią odpowiedź. http://stackoverflow.com/questions/6506897/csrf-token-missing-or-incorrect-while-post-parameter-via-ajax-in-django/6533544#6533544 – sigurd

Odpowiedz

10

Jest method explained here.

Składa się z dodania nagłówka X-CSRFToken na każdym żądaniu ajax.

Wykonuje się to przez zahaczenie zdarzenia jQuery.ajaxSend, więc wszystko odbywa się automatycznie (wystarczy skopiować i minąć ich kod, i uruchomić go raz przed pierwszym zgłoszeniem do ajax).

+0

Tak, przeczytałem. Ale nie wiem, jak go używać i gdzie go dodać = /? –

+0

umieścić kod tuż po '' i to wszystko, jak się wydaje. – arnaud576875

+0

Położyłem ten kod po zakończeniu '$ (" # login "). Live (" kliknij ", funkcja() {funkcja - to nic nie zmieniło :(Ten kod musi być w osobnym pliku? –

3

Próbowałem rozwiązać ten sam problem, a ponieważ arnaud576875 mówi, że musisz dodać nagłówek tokenu csrf na każdym żądaniu ajaxowym, tak jak w dokumentach Django mówi https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax I wykonaj ten kod przed każdym żądaniem Ajaxa.

Ale jest coś dodatkowego, musisz znaleźć sposób na załadowanie tokena csrf do ciasteczek swojej aplikacji zanim spróbujesz wykonać dowolne żądanie AJAX, po wielu bolesnych godzinach szukania nie mogłem znaleźć konkretnej odpowiedzi o tym, jak to zrobić, znalazłem to, aby upewnić się, że Twój widok wysyła token csrf w pliku cookie, możesz użyć ensure_csrf_token() do każdego widoku, który chcesz otrzymać token https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#django.views.decorators.csrf.ensure_csrf_cookie, co wydaje się działać dla wielu osób, ale nie zadziałał dla mnie.

Innym sposobem jest użycie starszej metody, dodając 'django.middleware.csrf.CsrfResponseMiddleware' do swojej MIDDLEWARE_CLASSES, ale nie polecam tej metody, ponieważ pozostawia wiele zagrożeń bezpieczeństwa. https://docs.djangoproject.com/en/1.2/ref/contrib/csrf/#legacy-method

Wszystkie te metody, które powiedziałem wcześniej, nie sprawdziły się u mnie. Sposób, w jaki zezwalam Ajaxowi na wykonanie niektórych żądań, jest następujący i jeśli ktoś uzna to za niebezpieczną metodę, proszę dać mi znać:

  1. Przejdź do pierwszego widoku, w które trafi Twój użytkownik, np./strona główna/strona.
  2. Włóż to przed przekierowaniem lub analizowania niczego request.META["CSRF_COOKIE_USED"] = True

I to, że jest to sposób, który działa dla mnie, ale jak już mówiłem, że nie jestem pewien, czy jest to odpowiednia metoda lub najbardziej bezpieczny jeden do osiągnięcia ochrony csrf.