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

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

我正在使用这个堆栈:

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

  • 我已经阅读了许多文章、手册、stackoverflow 主题、谷歌随机结果、博客等,但都非常不推荐。

    使用实用的方法 (tl; dr here) 我只需要在不同的服务器状态下在 Devise 3 和 Backbone 之间进行一次真正的 session 并保持它,就像两个独立的项目一样。远程登录,你懂的。

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

    谢谢你们。

    最佳答案

    就我个人而言,我在我的项目中遇到了同样的情况,Angular 而不是 Backbone 作为前端,Rails 4 API with Devise。我会尽量为你总结一下,假设我回答了你的问题。

    要在您的场景中正确使用 session ,您需要确保:

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

  • 请阅读 this article about CORS .如果您不熟悉 CORS,这篇文章应该为我的回答提供必要的背景。关于CSRF保护的一些信息是here

    这是您的场景分步说明:
  • Backbone.js 发送 GET请求如 http://yourserver/signin
  • Rails Server 发送将存储在浏览器中的 session cookie 和 CSRF token ,它可以存储在您的 Backbone 应用程序中的某个位置。
  • Backbone.js 发送 POST请求使用用户凭据(名称、密码)和 CSRF token 在 header 中以及当前未授权 session 在 cookie 中。请求包含 session 信息至关重要。否则它会在 Rails 端被授予不同的 CSRF token ,你会得到 WARNING: Can't verify CSRF token authenticity信息。
  • 如果凭据正确,Backbone.js 将返回授权 session 。

  • 以下是可以使其工作的方法:
  • Rails 后端应该正确响应来自前端的请求。这意味着它应该:
  • 回复 OPTIONS请求(预检请求)
  • 发送正确的 CORS header
  • 能够与前端通信CSRF token
  • 前端应该:
  • 能够使用凭据发送请求
  • 获取并使用正确的CSRF token

  • 教 Rails 后端响应 CORS 请求的最简单方法是使用
    rack-cors gem 。这也将提供正确的 CORS header 。
    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 token 。自定义设计 Controller 应该完美地处理这个任务。
    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
    

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

    在 config/routes.rb 中的某处不要忘记指定您现在正在使用自定义 Controller :
    /config/routes.rb
      devise_for :users, :controllers => {:sessions => "sessions"}
    

    现在,到前端。请看 this script覆盖标准 Backbone.sync并处理与 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);
      };
     }
    

    我不确定这是否有资格作为对您问题的完整答案,但至少可以从它开始。这可能不是最好的方法,但它是方法。如果您有任何问题,请告诉我。

    关于backbone.js - 使用 Devise 3 和 Backbone 进行用户身份验证的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21483894/

    相关文章:

    javascript - Backbone ListenTo 不会将 jquery 函数作为处理程序触发

    javascript - 主干听定制集合?

    php - 使用OOP PHP制作登录屏幕

    ruby-on-rails - Rails + 设计 : Wrong Sign out message

    ruby-on-rails - 从 Devise url 中删除模型

    javascript - 使用嵌套对象验证 Backbone 模型

    javascript - 主干中(view.$el 和 $(view.el))之间的差异

    login - 如何在 IdentityServer4 中进行多步登录?

    authentication - 持久性 "Remember Me"Cookie 的竞争条件

    ruby-on-rails - 为 Rails 4 : why should you keep user profile data on a separate table to the Devise User models table 设计