backbone.js - What is the best way to user authentication with Devise 3 and Backbone? -


i'm working stack:

  • core api restful rails 4 , devise 3.2
  • another app/stance backbone

i have read many articles, manuals, stackoverflow topics, google random results, blogs, etc, deprecated.

using practical approach (tl;dr here) need real session between devise 3 , backbone in different server stances , holding it, 2 separate projects. remote login, know.

i'm stuck appreciate suggestions.

thank guys.

personally have same situation in project angular instead of backbone front-end , rails 4 api devise. try sum things in assumption got question right.

to work correctly sessions in scenario need sure that:

  • browsers handle communication correctly (i.e. don't mess data because requests not comply cors policies)
  • and, requests through rails csrf protection

please, read this article cors. if not familiar cors article should provide necessary background answer. info csrf protection here

here scenario step-by-step:

  1. backbone.js sends get request such http://yourserver/signin
  2. rails server sends session cookie stored in browser , csrf token, can stored somewhere within backbone application.
  3. backbone.js sends post request user credentials (name, password) , csrf token in headers , current unauthorized session in cookies. crucial request contains session information. otherwise granted different csrf token on rails side , warning: can't verify csrf token authenticity message.
  4. backbone.js gets authorized session if credentials correct.

here can done working:

  1. rails backend should respond correctly requests front-end. means should:

    • respond options requests (preflight requests)
    • send correct cors headers
    • able communicate csrf token front-end
  2. front end should:

    • able send requests credentials
    • obtain , use correct csrf token

the simplest way teach rails back-end respond cors requests use rack-cors gem. provide correct cors headers.

config.middleware.insert_before warden::manager, rack::cors   allow     origins '*' # it's highly recommended specify correct origin     resource '*',          :headers => :any,          :methods => [:get, :post, :options], # 'options' important                                              # preflight requests         :expose  => ['x-csrf-token']   #allows usage of token on front-end   end end 

last thing on backend side provide csrf token. custom devise controller should handle task perfectly.

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 

note need csrf token when send first get request (new), when submit credentials through post request (create) , when sign out of application sending delete request (destroy). if don't send csrf token on sign out won't able sign in without reloading page.

and somewhere in config/routes.rb don't forget specify using custom controller:

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

now, front-end. please, have @ this script overrides standard backbone.sync , handles communication rails server. couple of corrections needed:

  beforesend: function( xhr ) {     if (!options.nocsrf) {       // dont have csrf-token in document anymore         //var token = $('meta[name="csrf-token"]').attr('content');        // new line #1       // csrf token application.       // see below how gets there.       var token = yourappname.csrftoken;        if (token) xhr.setrequestheader('x-csrf-token', token);          // new line #2       // include session information in requests       xhr.withcredentials = true;     }    //..some code omitted   //................    // trigger sync end event   var complete = options.complete;   params.complete = function(jqxhr, textstatus) {      // new lines #3,4      // if response includes csrf token need remember      var token = jqxhr.getresponseheader('x-csrf-token')       if (token) yourappname.csrftoken = token;       model.trigger('sync:end');      if (complete) complete(jqxhr, textstatus);   };  } 

i'm not sure qualifies complete answer question, @ least start from. might not best way, way. let me know if have questions.


Comments

Popular posts from this blog

html - Sizing a high-res image (~8MB) to display entirely in a small div (circular, diameter 100px) -

java - IntelliJ - No such instance method -

identifier - Is it possible for an html5 document to have two ids? -