Rozwijam aplikację Rails z interfejsem API REST w celu uzyskania dostępu z aplikacji mobilnej.Jak upewnić się, że Rails API jest zabezpieczony przed CSRF?
Działa całkiem dobrze. Gdy użytkownik loguje się z aplikacji mobilnej, otrzymuje auth_token
, której używa w swoich przyszłych żądaniach do API. Problem polega na tym, że interfejs API jest również dostępny z internetu, przechodząc do ścieżki/api/v1/... iz tego powodu musi być chroniony przed CSRF.
Mam klasę BaseApiController
, która dziedziczy po ApplicationController
z włączoną wersją protect_from_forgery
. Oto przykład:
class Api::V1::BaseApiController < ApplicationController
# ...
end
class ApplicationController < ActionController::Base
protect_from_forgery
# ...
end
Teraz, kiedy ja non-GET żądania do mojego API, z auth_token
, moja prośba zostanie zakończone powodzeniem, ale w dziennikach widzę słynny WARNING: Can't verify CSRF token authenticity
. Jeśli usuniemy protect_from_forgery
z mojego BaseApiController
, nie otrzymam żadnych ostrzeżeń (oczywiście), ale wtedy moje API jest podatne na ataki CSRF (stworzyłem prosty formularz HTML, który z powodzeniem zmienia dane w domenach, gdy nie ma protect_from_forgery
).
Moje pytanie brzmi: jak zapewnić, że moje API pozostanie bezpieczne, ale także usuwać ostrzeżenie podczas wykonywania próśb nie-GET?
Oto jedno z rozwiązań, jakie wymyślić, ale wygląda bardziej jak hack i wykonuje jeden dodatkowy zapytanie DB:
class Api::V1::BaseApiController < ApplicationController
# ...
def verified_request?
super || User.where(authentication_token: params['auth_token']).count > 0
end
end
Więcej szczegółów na temat projektu: Szyny 3.2.14, opracowania, AngularJS. Kod źródłowy projektu można znaleźć pod numerem here.