Я разрабатываю мобильное приложение Ionic
, чтобы поговорить с моим сервером Rails
с использованием API JSON. Я прочитал, что AngularJS автоматически обрабатывает защиту XSRF, отправив заголовок X-XSRF-TOKEN
в запрос POST
если первый GET
возвращает файл cookie с именем XSRF-TOKEN
Я обновил Rails application_controller.rb
следующим образом:
class ApplicationController < ActionController::Base
protect_from_forgery
after_filter :set_access_control_headers
after_filter :set_csrf_cookie_for_ng
def after_sign_in_path_for(resource)
main_path
end
def after_sign_out_path_for(resource)
login_path
end
##
# Sets headers to support AJAX Cross-Origin Resource Sharing.
# This is only needed for testing within browser (i.e. mobile apps do not need it).
##
def set_access_control_headers
# hosts who can make AJAX requests
headers['Access-Control-Allow-Origin'] = 'http://localhost:8100'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'accept, content-type, x-xsrf-token'
# allow clients to use cookies to track session state
headers['Access-Control-Allow-Credentials'] = 'true'
end
##
# Sets a cookie containing an XSRF token. This should be returned by the
# client as a header field named 'X-XSRF-TOKEN'
def set_csrf_cookie_for_ng
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
protected
def verified_request?
super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
end
end
Код AngularJS:
$http({
method: 'POST',
url: $scope.getBackendUrl() + '/reports.json',
params: params,
withCredentials: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
Я взял дампы Wireshark
и вижу, что сервер Rails отправляет через Cookie (и я могу прочитать это в AngularJS). Тем не менее, AngularJS не отправляет заголовок X-XSRF-TOKEN
на мой сервер Rails-сервера, вызывая WARNING: Can't verify CSRF token authenticity
.
Я прочитал кучу вопросов SO безрезультатно. Например, заголовки XSRF не устанавливаются в AngularJS
Я добавил материал заголовка CORS, чтобы я мог протестировать его в Chrome. Опять же, я вижу, что cookie проходит с сервера, но заголовок не отправляется обратно. Однако cookie отправляется обратно в поле заголовка "Cookie".
Может ли кто-нибудь увидеть то, что у меня пропало, или что я могу попытаться решить? В настоящее время я разбираю поле заголовка Cookie
в запросе, чтобы вытащить токен и проверить подлинность, чтобы обойти проблему во время тестирования.
def verified_request?
# should just need to do the below, but for some reason AngularJS is not setting 'X-XSRF-TOKEN'
#super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
if(super)
true
else
cookie = request.headers['Cookie'] || ""
value = cookie.nil? ? "" : CGI.unescape( cookie.gsub(/.*XSRF-TOKEN=(.+);.*/, '\1') )
form_authenticity_token == value
end
end
Версии:
- Рельсы 3.2.3
- Ионный 1.1.6 (который связывает в AngularJS)