首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Rails CSRF Protection + Angular.js: protect_from_forgery让我可以在POST中注销

Rails CSRF Protection + Angular.js: protect_from_forgery让我可以在POST中注销
EN

Stack Overflow用户
提问于 2013-02-07 00:41:14
回答 7查看 47.1K关注 0票数 130

如果在application_controller中提到了protect_from_forgery选项,那么我可以登录并执行任何GET请求,但是在第一次POST请求时,Rails会重置会话,这会将我注销。

我暂时关闭了protect_from_forgery选项,但希望在Angular.js中使用它。有什么方法可以做到这一点吗?

EN

回答 7

Stack Overflow用户

发布于 2013-02-07 01:30:37

如果你使用的是默认的Rails CSRF保护(<%= csrf_meta_tags %>),你可以这样配置你的Angular模块:

代码语言:javascript
复制
myAngularApp.config ["$httpProvider", ($httpProvider) ->
  $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
]

或者,如果您没有使用CoffeeScript (什么!?):

代码语言:javascript
复制
myAngularApp.config([
  "$httpProvider", function($httpProvider) {
    $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
  }
]);

如果您愿意,您可以只在非GET请求上发送header,如下所示:

代码语言:javascript
复制
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,它涵盖了服务器上的所有基础,而不是客户端。

票数 79
EN

Stack Overflow用户

发布于 2013-12-14 01:18:20

angular_rails_csrf gem会自动向所有控制器添加对HungYuHei's answer中描述的模式的支持:

代码语言:javascript
复制
# Gemfile
gem 'angular_rails_csrf'
票数 29
EN

Stack Overflow用户

发布于 2014-05-28 23:53:38

合并了前面所有答案的答案依赖于您使用的是Devise身份验证gem。

首先,添加gem:

代码语言:javascript
复制
gem 'angular_rails_csrf'

接下来,将rescue_from块添加到application_controller.rb中:

代码语言:javascript
复制
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应用程序。

代码语言:javascript
复制
# 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')
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14734243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档