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:
- backbone.js sends
get
request suchhttp://yourserver/signin
- rails server sends session cookie stored in browser , csrf token, can stored somewhere within backbone application.
- 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. - backbone.js gets authorized session if credentials correct.
here can done working:
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
- respond
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
Post a Comment