Pracowałem nad nową aplikacją Rails 4 (na Ruby 2.0.0-p0), kiedy napotkałem pewne problemy z tokenami autentyczności.
Podczas pisania kontrolera, który reaguje na json (przy użyciu respond_to
metody klasy), doszedłem do create
akcji, w której zacząłem uzyskiwać ActionController::InvalidAuthenticityToken
wyjątki, gdy próbowałem utworzyć rekord za pomocą curl
.
Upewniłem się, że ustawiłem -H "Content-Type: application/json"
i ustawiłem dane, -d "<my data here>"
ale nadal nie miałem szczęścia.
Próbowałem napisać ten sam kontroler przy użyciu Rails 3.2 (na Ruby 1.9.3) i nie dostałem żadnych problemów z tokenem autentyczności. Rozejrzałem się i zobaczyłem, że w Railsie 4 wprowadzono pewne zmiany dotyczące tokenów autentyczności. Z tego, co rozumiem, nie są już one automatycznie wstawiane do formularzy? Przypuszczam, że to w jakiś sposób wpływa na typy treści inne niż HTML.
Czy jest jakiś sposób na obejście tego bez konieczności żądania formularza HTML, wyłapywania tokena autentyczności, a następnie wysyłania kolejnego żądania z tym tokenem? A może zupełnie brakuje mi czegoś, co jest całkowicie oczywiste?
Edycja: Właśnie próbowałem utworzyć nowy rekord w nowej aplikacji Rails 4 przy użyciu rusztowania bez zmiany czegokolwiek i napotykam ten sam problem, więc chyba nie zrobiłem tego.
before_action
który sprawdza format i czy żądanie jest zweryfikowane. Nie znam żadnego wbudowanego sposobu ustawiania warunków.skip_before_action :verify_authenticity_token
w kontrolerze aplikacji mojego API, aby to działało.:verify_authenticy_token
więcej wyłączać w Rails 4.2. Domyślnie jest to:null_session
, co, jak sama nazwa wskazuje, po prostu wysyła żądanie bez sesji. Zamiast tego możesz zweryfikować żądanie za pomocą klucza API.Zamiast wyłączać ochronę csrf, lepiej dodać następujący wiersz kodu do formularza
a jeśli używasz form_for lub form_tag do wygenerowania formularza, wówczas automatycznie doda powyższy wiersz kodu w formularzu
źródło
Dla mnie zadziałało dodanie następującego wiersza do formularza:
źródło
=token_tag nil
lub (w .erb)<%= token_tag nil %>
Nie sądzę, że dobrze jest wyłączyć ochronę CSRF, o ile nie implementujesz wyłącznie interfejsu API.
Przeglądając dokumentację API Rails 4 dla ActionController , zauważyłem, że możesz wyłączyć ochronę przed fałszowaniem na kontrolerze lub podstawie metody.
Na przykład, aby wyłączyć ochronę CSRF dla metod, których możesz użyć
źródło
Wystąpił ten sam problem. Naprawiono to poprzez dodanie do mojego kontrolera:
źródło
Próbowałeś?
źródło
Ten oficjalny dokument - mówi o tym, jak prawidłowo wyłączyć ochronę przed fałszowaniem dla interfejsu API http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html
źródło
Jest to funkcja bezpieczeństwa w Railsach. Dodaj ten wiersz kodu w postaci:
Dokumentację można znaleźć tutaj: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html
źródło
Funkcje te zostały dodane do celów bezpieczeństwa i ochrony przed fałszowaniem.
Jednak, aby odpowiedzieć na twoje pytanie, oto kilka danych wejściowych. Możesz dodać te linie po nazwie kontrolera.
Tak jak
Oto kilka linii dla różnych wersji szyn.
Szyny 3
Szyny 4 :
Jeśli zamierzasz wyłączyć tę funkcję bezpieczeństwa dla wszystkich procedur kontrolera, możesz zmienić wartość protect_from_forgery na : null_session w pliku application_controller.rb.
Tak jak
źródło
Jeśli używasz jQuery z szynami, zachowaj ostrożność, pozwalając na dostęp do metod bez weryfikacji tokena autentyczności.
jquery-ujs może zarządzać tokenami za ciebie
Powinieneś go mieć już jako część klejnotu jquery-rails, ale może być konieczne dołączenie go do application.js z
To wszystko, czego potrzebujesz - Twoje wywołanie ajaxowe powinno teraz działać
Aby uzyskać więcej informacji, zobacz: https://github.com/rails/jquery-ujs
źródło
Dodaj
authenticity_token: true
do znacznika formularzaźródło
Podczas definiowania własnego formularza HTML należy dołączyć ciąg tokena uwierzytelniającego, który ze względów bezpieczeństwa należy przesłać do kontrolera. Jeśli używasz szyn pomocnika formularza do wygenerowania tokena autentyczności, dodajesz go do formularza w następujący sposób.
Rozwiązaniem problemu jest więc dodanie pola token_ autentyczności lub użycie szyn pomocników zamiast zagrażać bezpieczeństwu itp.
źródło
application/json
.Wszystkie moje testy działały dobrze. Ale z jakiegoś powodu ustawiłem moją zmienną środowiskową na nietestową:
Zapomniałem rozbroić tę zmienną, z powodu której zacząłem uzyskiwać
ActionController::InvalidAuthenticityToken
wyjątek.Po rozbrojeniu
$RAILS_ENV
moje testy znów zaczęły działać.źródło