使用Devise 3和Backbone进行用户身份验证的最佳方法是什么?

时间:2014-01-31 15:37:00

标签: backbone.js login devise ruby-on-rails-4

我正在使用这个堆栈:

  • 使用Rails 4和Devise 3.2的核心API RESTful
  • Backbone的另一个应用程序/立场

我已阅读过很多文章,手册,stackoverflow主题,google随机结果,博客等,但都非常弃用。

使用实用的方法 (tl; dr here)我只需要在不同的服务器站点中获取Devise 3和Backbone之间的真实会话并保存它,就像两个单独的项目一样。远程登录,你知道。

我真的很坚持,所以我非常感谢你的建议。

谢谢你们。

1 个答案:

答案 0 :(得分:11)

我个人在使用Angular而不是Backbone作为前端和使用Devise的Rails 4 API的项目中具有相同的情况。假设我的问题正确,我会尽力为你总结一下。

要正确使用场景中的会话,您需要确保:

  • 浏览器正确处理通信(即它们不会弄乱您的数据,因为请求不符合CORS策略)
  • 并且,您的请求通过Rails CSRF保护

请阅读this article about CORS。如果您不熟悉CORS,那么文章应该为我的答案提供必要的背景知识。有关CSRF保护的一些信息是here

以下是您的方案一步一步:

  1. Backbone.js发送GET请求,例如http://yourserver/signin
  2. Rails服务器发送将存储在浏览器中的会话cookie和CSRF令牌,该令牌可以存储在Backbone应用程序中的某个位置。
  3. Backbone.js发送POST请求,其中包含用户凭据(名称,密码)和标头中的CSRF令牌以及Cookie中的当前未授权会话。请求包含会话信息至关重要。否则,它将在Rails端被授予不同的CSRF令牌,您将收到WARNING: Can't verify CSRF token authenticity消息。
  4. 如果凭据正确,Backbone.js将获得授权会话。
  5. 以下是如何使其发挥作用:

    1. Rails后端应该正确响应来自前端的请求。这意味着它应该:

      • 回复OPTIONS次请求(预检请求)
      • 发送正确的CORS标头
      • 能够与前端沟通CSRF令牌
    2. 前端应该:

      • 能够发送带凭据的请求
      • 获取并使用正确的CSRF令牌
    3. 教会Rails后端响应CORS请求的最简单方法是使用 rack-cors宝石。这也将提供正确的CORS标头。

      config.middleware.insert_before Warden::Manager, Rack::Cors do
        allow do
          origins '*' # it's highly recommended to specify the correct origin
          resource '*', 
              :headers => :any, 
              :methods => [:get, :post, :options], # 'options' is really important 
                                                  # for preflight requests
              :expose  => ['X-CSRF-Token']   #allows usage of token on the front-end
        end
      end
      

      后端的最后一件事是提供CSRF令牌。自定义设计控制器应该完美地处理这个任务。

      class SessionsController < Devise::SessionsController
      
          after_action :set_csrf_header, only: [:new, :create, :destroy]
      
          #...
      
          protected
      
          def set_csrf_header
            response.headers['X-CSRF-Token'] = form_authenticity_token
          end
      end
      

      请注意,当您通过GET请求(new)提交凭据时以及退出时,在发送第一个POST请求(create)时需要CSRF令牌发送DELETE请求(destroy)的应用程序。如果您在注销时未发送CSRF令牌,则无法在不重新加载页面的情况下登录。

      在config / routes.rb中的某处,不要忘记指定您现在使用的是自定义控制器:

      /config/routes.rb
        devise_for :users, :controllers => {:sessions => "sessions"}
      

      现在,到了前端。请查看覆盖标准Backbone.sync的{​​{3}}并处理与Rails服务器的通信。 需要进行几次修正几乎是好的:

        beforeSend: function( xhr ) {
          if (!options.noCSRF) {
            // we dont have csrf-token in the document anymore  
            //var token = $('meta[name="csrf-token"]').attr('content');
      
            // New Line #1
            // we will get CSRF token from your application.
            // See below for how it gets there.
            var token = YourAppName.csrfToken;
      
            if (token) xhr.setRequestHeader('X-CSRF-Token', token);  
      
            // New Line #2
            // this will include session information in the requests
            xhr.withCredentials = true;
          }
      
        //..some code omitted
        //................
      
        // Trigger the sync end event
        var complete = options.complete;
        params.complete = function(jqXHR, textStatus) {
           // New Lines #3,4
           // If response includes CSRF token we need to remember it
           var token = jqXHR.getResponseHeader('X-CSRF-Token') 
           if (token) YourAppName.csrfToken = token;
      
           model.trigger('sync:end');
           if (complete) complete(jqXHR, textStatus);
        };
       }
      

      我不确定这是否可以作为您问题的完整答案,但至少它可以从一开始就有所帮助。它可能不是最好的方式,但它是方式。如果您有任何疑问,请告诉我。

相关问题