Token Autentyczności Rails 4

Pracowałem nad nową aplikacją Rails 4 (na Ruby 2.0.0-p0), kiedy napotkałem problemy z tokenem autentyczności.

Podczas pisania kontrolera odpowiadającego na json (używając metody klasy respond_to), dotarłem do akcji create, którą zacząłem otrzymywać ActionController::InvalidAuthenticityToken, kiedy próbowałem utworzyć rekord używając curl.

Upewniłem się, że ustawiłem -H "Content-Type: application/json" i ustawiłem dane za pomocą -d "<my data here>", ale i tak bez powodzenia.

Próbowałem napisać ten sam kontroler używając Rails 3.2 (Na Ruby 1.9.3) i nie mam problemy z autentycznością. Szukałem i zobaczyłem, że w Rails 4 zaszły pewne zmiany z tokenami autentyczności. Z tego co rozumiem, nie są już automatycznie wstawiane do formularzy? Przypuszczam, że w jakiś sposób wpływa to na typy treści innych niż HTML.

Czy jest jakiś sposób, aby obejść to bez konieczności żądania formularza HTML, przechwytywania tokenu autentyczności, a następnie składania kolejnego żądania z tym tokenem? A może zupełnie brakuje mi czegoś, co jest całkowicie oczywiste?

Edit: właśnie próbowałem stworzyć nowy rekord w nowej aplikacji Rails 4 używając rusztowania bez zmiany czegokolwiek i mam ten sam problem, więc myślę, że to nie jest coś, co zrobiłem.

Author: John Bachir, 0000-00-00

5 answers

Chyba właśnie to rozgryzłem. Zmieniłem (nowy) domyślny

protect_from_forgery with: :exception

Do

protect_from_forgery with: :null_session

Zgodnie z komentarzem w ApplicationController.

# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.

Możesz zobaczyć różnicę patrząc na źródło request_forgery_protecton.rb, a dokładniej na następujące linie:

In Rails 3.2:

# This is the method that defines the application behavior when a request is found to be unverified.
# By default, \Rails resets the session when it finds an unverified request.
def handle_unverified_request
  reset_session
end

In Rails 4:

def handle_unverified_request
  forgery_protection_strategy.new(self).handle_unverified_request
end

Który wywoła następujący :

def handle_unverified_request
  raise ActionController::InvalidAuthenticityToken
end
 271
Author: alexcoco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-05 16:26:45

Zamiast wyłączać ochronę csrf, lepiej dodać następujący wiersz kodu do formularza

<%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %> 

I jeśli używasz form_for lub form_tag do generowania formularza, to automatycznie doda powyższy wiersz kodu w formularzu

 69
Author: xiaoboa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 04:00:03

Dodanie następującej linijki do formularza zadziałało dla mnie:

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
 68
Author: Carlos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-24 23:56:44

Nie wydaje mi się, aby było dobrze wyłączać ochronę CSRF tak długo, jak długo nie implementujesz wyłącznie API.

Przeglądając dokumentację API Rails 4 dla ActionController odkryłem, że można wyłączyć ochronę przed fałszerstwami dla każdego kontrolera lub bazy metod.

Na przykład, aby wyłączyć ochronę CSRF dla metod, których można użyć

class FooController < ApplicationController
  protect_from_forgery except: :index
 32
Author: roamingthings,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-27 01:47:23

Natknąłem się na s

 8
Author: ,
Warning: date() expects parameter 2 to be long, string given in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54