Jak mogę pobrać token CSRF do przekazania z żądaniem JSON?
Wiem, że ze względów bezpieczeństwa Railsy sprawdzają token CSRF na wszystkich typach żądań (w tym JSON / XML).
Mógłbym włożyć kontroler skip_before_filter :verify_authenticity_token
, ale straciłbym ochronę CRSF (nie wskazane :-)).
Ta podobna (wciąż nie akceptowana) odpowiedź sugeruje
Pobierz token za pomocą
<%= form_authenticity_token %>
Pytanie brzmi jak? Czy muszę najpierw wywołać którąkolwiek z moich stron, aby pobrać token, a następnie przeprowadzić prawdziwe uwierzytelnienie za pomocą Devise? Czy jest to jednorazowa informacja, którą mogę pobrać z mojego serwera, a następnie konsekwentnie używać (do momentu ręcznej zmiany jej na samym serwerze)?
źródło
protect_from_forgery with: :null_session, :if => Proc.new { |c| c.request.format == 'application/json' }
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
2) Niepowiązane z tym pytaniem, ale związane z tematem POSTING JSON z iOS, ponieważ używamAFNetworking
i Railsy niemanager.requestSerializer = [AFJSONRequestSerializer serializer];
Możesz wysłać token CSRF po pomyślnym zalogowaniu, używając niestandardowego nagłówka.
Np. Umieść to w swoich sesjach # create:
response.headers['X-CSRF-Token'] = form_authenticity_token
Przykładowy nagłówek odpowiedzi logowania zawierający token CSRF:
HTTP/1.1 200 OK Cache-Control: max-age=0, private, must-revalidate Connection: Keep-Alive Content-Length: 35 Content-Type: application/json; charset=utf-8 Date: Mon, 22 Oct 2012 11:39:04 GMT Etag: "9d719d3b9aabd413c3603e04e8a3933d" Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-10-12) Set-Cookie: [cut for readability] X-Csrf-Token: PbtMPfrszxH6QfRcWJCCyRo7BlxJUPU7HqC2uz2tKGw= X-Request-Id: 178746992d7aca928c876818fcdd4c96 X-Runtime: 0.169792 X-Ua-Compatible: IE=Edge
Ten token jest ważny do momentu ponownego zalogowania lub (wyloguj się, jeśli obsługujesz to za pośrednictwem swojego interfejsu API). Twój klient może wyodrębnić i zapisać token z nagłówków odpowiedzi logowania. Następnie każde żądanie POST / PUT / DELETE musi ustawić nagłówek X-CSRF-Token z wartością otrzymaną w czasie logowania.
Przykładowe nagłówki POST z tokenem CSRF:
POST /api/report HTTP/1.1 Accept: application/json Accept-Encoding: gzip, deflate, compress Content-Type: application/json; charset=utf-8 Cookie: [cut for readability] Host: localhost:3000 User-Agent: HTTPie/0.3.0 X-CSRF-Token: PbtMPfrszxH6QfRcWJCCyRo7BlxJUPU7HqC2uz2tKGw=
Dokumentacja: form_authenticity_token
źródło
Naprawdę najprostszy sposób. Nie przejmuj się zmianą nagłówków.
Upewnij się że masz:
w Twoim
layouts/application.html.erb
Po prostu wykonaj ukryte pole wejściowe, takie jak:
<input name="authenticity_token" type="hidden" value="<%= form_authenticity_token %>"/>
Lub jeśli chcesz wysłać post w jquery Ajax:
$.ajax({ type: 'POST', url: "<%= someregistration_path %>", data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "<%= form_authenticity_token %>" }, error: function( xhr ){ alert("ERROR ON SUBMIT"); }, success: function( data ){ //data response can contain what we want here... console.log("SUCCESS, data="+data); } });
Zasadniczo, kiedy publikujesz swoje dane json, po prostu dodaj prawidłowe pole autentyczności_token do
post
danych, a ostrzeżenie powinno zniknąć ...źródło
= token_tag(nil)
(zero jest ważne)Rozwiązałem ten błąd w ten sposób:
class ApplicationController < ActionController::Base protect_from_forgery skip_before_action :verify_authenticity_token, if: :json_request? protected def json_request? request.format.json? end end
Źródło: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html
źródło
protect_from_forgery with: :exception, unless: -> { request.format.json? }
i zadziałał dla mnie. Dzięki.Niepokojące jest to, że w Railsach 3.2.3 otrzymujemy teraz ostrzeżenie CSRF w pliku production.log, ale post nie zawodzi! Chcę, żeby to się nie udało, ponieważ chroni mnie przed atakami. I możesz dodać token csrf za pomocą jquery przed filtrem btw:
http://jasoncodes.com/posts/rails-csrf-vulnerability
źródło
Użyłem poniżej. Używasz include? więc jeśli typ zawartości to application / json; charset = utf-8, to nadal działa.
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format.include? 'application/json' }
źródło
Ta odpowiedź jest lepsza.
Możesz zachować walidację CSRF-TOKEN bez dodatkowego wysiłku (token jest dołączany) przed wysłaniem XMLHttpRequest. Bez JQuery, nic po prostu skopiuj / wklej i odśwież.
Po prostu dodaj ten kod.
(function() { var send = XMLHttpRequest.prototype.send, token = $('meta[name=csrf-token]').attr('content'); XMLHttpRequest.prototype.send = function(data) { this.setRequestHeader('X-CSRF-Token', token); return send.apply(this, arguments); }; }());
źródło
Miałem ten sam problem z następującą wersją Railsów:
gem 'rails',: git => 'git: //github.com/rails/rails.git',: branch => '3-2-stable'
Zaktualizowałem do wersji 3.2.2 i teraz wszystko działa dobrze. :)
gem 'rails', '3.2.2'
źródło
WARNING: Can't verify CSRF token authenticity
Dziś wieczorem napotkałem ten sam problem. Dzieje się tak, ponieważ po zalogowaniu ostatni token csrf nie jest już ważny. To, co zrobiłem, to:
$("meta[name=csrf-token]").attr('content', '<%= form_authenticity_token %>');
w twojej aplikacji / views / devise / session / create.js.rb.Teraz ma prawidłowy token csrf :) Mam nadzieję, że to pomoże
źródło
Również w trybie programowania / testowania.
protect_from_forgery with: :exception unless %w(development test).include? Rails.env
To ostrzeżenie pojawia się, ponieważ używasz
:null_session
, w Railsach 4.1 działa domyślnie, jeśli niewith:
podano opcji.źródło