如果在application_controller中提到了protect_from_forgery
选项,那么我可以登录并执行任何GET请求,但是在第一次POST请求时,Rails会重置会话,这会将我注销。
我暂时关闭了protect_from_forgery
选项,但希望在Angular.js中使用它。有什么方法可以做到这一点吗?
发布于 2013-02-07 01:30:37
如果你使用的是默认的Rails CSRF保护(<%= csrf_meta_tags %>
),你可以这样配置你的Angular模块:
myAngularApp.config ["$httpProvider", ($httpProvider) ->
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
]
或者,如果您没有使用CoffeeScript (什么!?):
myAngularApp.config([
"$httpProvider", function($httpProvider) {
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
}
]);
如果您愿意,您可以只在非GET请求上发送header,如下所示:
myAngularApp.config ["$httpProvider", ($httpProvider) ->
csrfToken = $('meta[name=csrf-token]').attr('content')
$httpProvider.defaults.headers.post['X-CSRF-Token'] = csrfToken
$httpProvider.defaults.headers.put['X-CSRF-Token'] = csrfToken
$httpProvider.defaults.headers.patch['X-CSRF-Token'] = csrfToken
$httpProvider.defaults.headers.delete['X-CSRF-Token'] = csrfToken
]
此外,请务必查看HungYuHei's answer,它涵盖了服务器上的所有基础,而不是客户端。
发布于 2013-12-14 01:18:20
angular_rails_csrf gem会自动向所有控制器添加对HungYuHei's answer中描述的模式的支持:
# Gemfile
gem 'angular_rails_csrf'
发布于 2014-05-28 23:53:38
合并了前面所有答案的答案依赖于您使用的是Devise
身份验证gem。
首先,添加gem:
gem 'angular_rails_csrf'
接下来,将rescue_from
块添加到application_controller.rb中:
protect_from_forgery with: :exception
rescue_from ActionController::InvalidAuthenticityToken do |exception|
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
render text: 'Invalid authenticity token', status: :unprocessable_entity
end
最后,将拦截器模块添加到您的angular应用程序。
# coffee script
app.factory 'csrfInterceptor', ['$q', '$injector', ($q, $injector) ->
responseError: (rejection) ->
if rejection.status == 422 && rejection.data == 'Invalid authenticity token'
deferred = $q.defer()
successCallback = (resp) ->
deferred.resolve(resp)
errorCallback = (resp) ->
deferred.reject(resp)
$http = $http || $injector.get('$http')
$http(rejection.config).then(successCallback, errorCallback)
return deferred.promise
$q.reject(rejection)
]
app.config ($httpProvider) ->
$httpProvider.interceptors.unshift('csrfInterceptor')
https://stackoverflow.com/questions/14734243
复制相似问题