2016-08-10 39 views
8

Na tej samej stronie Rails 4 app mamSzyny authenticity_token na formularzu vs CSRF tokena

w głowę:

<meta name="csrf-param" content="authenticity_token" /> 
<meta name="csrf-token" content="some_token" /> 

i poniżej w organizmie:

<form action="/someaction" method="post"> 
<input name="utf8" type="hidden" value="&#x2713;" /> 
<input type="hidden" name="_method" value="patch" /> 
<input type="hidden" name="authenticity_token" value="another_token" /> 

Token csrf wymaga wywołań js. Ale dlaczego token formularza różni się od tokenu csrf? Który z dwóch tokenów jest używany przy składaniu formularzy?

Odpowiedz

0

Zrobiłem kilka badań, aby odpowiedzieć na twoje pytanie, a oto wyniki.

Przede wszystkim przyjrzyjmy się tej części:

<meta name="csrf-param" content="authenticity_token" /> 
<meta name="csrf-token" content="some_token" /> 

Ta część jest wytwarzana metodą csrf_meta_tags. Z kodu źródłowego widzimy, że:

  1. „content” wartość atrybutu <meta name="csrf-param" /> pochodzi z request_forgery_protection_token i domyślnie jest :authenticity_token.

  2. „zawartość” wartość atrybutu <meta name="csrf-token" /> pochodzi z form_authenticity_token sposobu, w którym znacznik jest pobieranej z sesji lub wygenerowane.

Teraz sprawdź tę część:

<input type="hidden" name="authenticity_token" value="another_token" /> 

od źródła widzimy, że:

  1. Ten ukryty wejście jest zwracany przez extra_tags_for_form metody.
  2. Wewnątrz extra_tags_for_form wywołuje metodę token_tag.
  3. token_tag Metoda przyjmuje token jako argument.
  4. Argument token_tag został wcześniej wyodrębniony z metody options z metody form_tag w metodzie html_options_for_form.

Więc jeśli nie ręcznie ustawić authenticity_token param w options do niestandardowego żeton i nie spełnia warunków, które prowadzą do ustawiania token wartość false (będzie mowa poniżej), token_tag metoda otrzyma nil i wywołaj tę samą metodę form_authenticity_token, która jest używana do tworzenia znaczników . Nawiasem mówiąc, w celu wypełnienia atrybutu input name używa on także request_forgery_protection_token, który jest używany przy generowaniu tagów <meta name="csrf-param" />.

A ponieważ wszystko to ma miejsce podczas tego samego żądania, wywołanie metody form_authenticity_token powinno zwrócić ten sam wynik w obu przypadkach.

Który z dwóch tokenów jest używany przy składaniu formularza?

Przy składaniu formularza zostanie użyty token z ukrytych danych wejściowych.

Reklamowe z <meta /> również mogą być stosowane, ale tylko wtedy, gdy są spełnione wszystkie niżej conditions (które sprawiają token argument token_tag metody być ustawiona na false) będzie:

  1. :remote => true powinny być przekazywane w options z form_tag .
  2. embed_authenticity_token_in_remote_forms config jest ustawione na false.
  3. authenticity_token nie został przekazany w options.

Dlaczego jednak żeton formularza różni się od tokena csrf?

Jeśli chodzi o to pytanie, być może ten problem występuje z powodu buforowania. Lub, prawdopodobnie, jeśli użyjesz klejnotu Turbolinks, może to spowodować ten problem (możesz to sprawdzić, jeśli całkowicie odświeżysz stronę i ponownie porównasz tokeny). Aby uzyskać więcej informacji na temat problemu z Turbolinks, sprawdź this question.

+0

Dzięki. Potrzebuję trochę czasu, aby spojrzeć na odpowiedź i zrozumieć ją. – thebravoman

+0

@thebravoman Czy to było pomocne? –

+0

To było, muszę przetestować kilka rzeczy z moją aplikacją, aby spróbować zrozumieć to całkowicie – thebravoman