如果protect_from_forgery
选项在application_controller提到的,然后我就可以登录并执行任何GET请求,但在第一个POST请求Rails的重置会话,它记录了我。
我把protect_from_forgery
选项暂时关闭,但想与Angular.js使用它。 是否有某种方式来做到这一点?
如果protect_from_forgery
选项在application_controller提到的,然后我就可以登录并执行任何GET请求,但在第一个POST请求Rails的重置会话,它记录了我。
我把protect_from_forgery
选项暂时关闭,但想与Angular.js使用它。 是否有某种方式来做到这一点?
我觉得从DOM读取CSRF价值是不是一个很好的解决方案,它只是一个解决方法。
下面是一个文件的形式angularJS官方网站http://docs.angularjs.org/api/ng.$http :
由于只在您的域中可以读取cookie中运行的JavaScript,您的服务器可以放心的是,XHR从JavaScript来在域上运行。
要充分利用这一点(CSRF保护),你的服务器需要设置令牌名为XSRF-TOKEN的第一个HTTP GET请求一个JavaScript可读会话cookie。 在随后的非GET请求的服务器可以验证cookie的比赛X-XSRF-TOKEN HTTP标头
下面是根据这些说明我的解决方案:
首先,设置Cookie:
# app/controllers/application_controller.rb
# Turn on request forgery protection
protect_from_forgery
after_action :set_csrf_cookie
def set_csrf_cookie
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
那么,我们应该核实每一个非GET请求令牌。
由于滑轨已经用相似的方法建立,我们可以只是简单的覆盖它追加我们的逻辑:
# app/controllers/application_controller.rb
protected
# In Rails 4.2 and above
def verified_request?
super || valid_authenticity_token?(session, request.headers['X-XSRF-TOKEN'])
end
# In Rails 4.1 and below
def verified_request?
super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
end
如果您使用的是默认的Rails CSRF保护( <%= csrf_meta_tags %>
),你可以配置你喜欢这个角模块:
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请求头:
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的答案 ,它涵盖了服务器,而不是在客户端上的所有基地。
该angular_rails_csrf宝石会自动为所描述的模式支持HungYuHei的回答您的所有控制器:
# Gemfile
gem 'angular_rails_csrf'
该合并所有以前的答案的答案,它依赖于你正在使用Devise
认证的宝石。
首先,添加宝石:
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
而最后,拦截模块添加到您的角度应用。
# 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')
我看到其他的答案,并认为他们是伟大的和深思熟虑。 我得到了我的Rails应用程序的工作,虽然什么我认为是一个简单的解决方案,所以我想我会分享。 我的Rails应用程序来使用这个默认的它,
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
end
我读了意见,并就好像这是我想要使用的角度,避免CSRF错误的东西。 我改成了这一点,
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :null_session
end
现在,它的作品! 我看不出有任何理由,这不应该工作,但我很乐意听到来自其他海报的一些见解。
我用从HungYuHei的回答内容在我的应用程序。 我发现,我不过是处理一些额外的问题,我使用的设计认证的一些原因,有些是因为我有我的申请得到了默认的:
protect_from_forgery with: :exception
我注意到相关堆栈溢出的问题,有答案 ,我写了一个更详细的博客文章 ,总结多方面考虑。 该溶液的是与此有关的,在应用控制器中的部分:
protect_from_forgery with: :exception
after_filter :set_csrf_cookie_for_ng
def set_csrf_cookie_for_ng
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
rescue_from ActionController::InvalidAuthenticityToken do |exception|
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
render :error => 'Invalid authenticity token', {:status => :unprocessable_entity}
end
protected
def verified_request?
super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
end
我发现了一个非常快速的黑客攻击了这一点。 所有我必须做的是以下几点:
一个。 在我看来,我初始化$scope
包含令牌变量,假设的形式之前,或者在控制器初始化甚至更好:
<div ng-controller="MyCtrl" ng-init="authenticity_token = '<%= form_authenticity_token %>'">
湾 在我的AngularJS控制器,节省了我的新的项目之前,我的代币添加到哈希:
$scope.addEntry = ->
$scope.newEntry.authenticity_token = $scope.authenticity_token
entry = Entry.save($scope.newEntry)
$scope.entries.push(entry)
$scope.newEntry = {}
做没有更多的需求。
angular
.module('corsInterceptor', ['ngCookies'])
.factory(
'corsInterceptor',
function ($cookies) {
return {
request: function(config) {
config.headers["X-XSRF-TOKEN"] = $cookies.get('XSRF-TOKEN');
return config;
}
};
}
);
它的工作对angularjs身边!