Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How use token authentication with Rails, Devise and Backbone.js?

I'm trying to build a mobile application with PhoneGap, jQuery Mobile and Backbone.js on the client-side - with a Rails 3 JSON API running server-side.

I know how to fetch the token from the server after being authenticated, but I don't know how to append the "token_auth" key/value to all the AJAX-requests Backbone.js will make to my server.

Here's my flow at the moment:

  1. User types in some form fields and hits "Log in"
  2. Backbone creates a new Player object with the email and password info.
  3. I run a Player.authenticate that sets the token to AUTHENTICATION_TOKEN
  4. All requests after this should append "auth_token=" + AUTHENTICATION_TOKEN

I've looked at http://documentcloud.github.com/backbone/#Sync for maybe overriding the AJAX calls - but that seems quite extreme for this simple task.

Does anyone have any experience with running Devise token_authentication and Backbone.js?

like image 863
theodorton Avatar asked Oct 16 '11 14:10

theodorton


3 Answers

The key is to introduce it in the Backbone.sync method.

Take a look at this implementation: https://github.com/codebrew/backbone-rails/blob/master/vendor/assets/javascripts/backbone_rails_sync.js

You can add it yourself this way:

Backbone.old_sync = Backbone.sync
Backbone.sync = function(method, model, options) {
    var new_options =  _.extend({
        beforeSend: function(xhr) {
            var token = $('meta[name="csrf-token"]').attr('content');
            if (token) xhr.setRequestHeader('X-CSRF-Token', token);
        }
    }, options)
    return Backbone.old_sync(method, model, new_options);
};

Check out this fiddle: http://jsfiddle.net/dira/ZcY3D/14/

like image 180
dira Avatar answered Nov 12 '22 02:11

dira


Why don't append it to all of your jquery ajax requests. It will add the auth_token to all of your ajax calls over jQuery. That might be useful when working directly with jQuery ajax (or libs that do so). But this might be a security issue as well (when you have ajax calls to other sites...).

// this is untested
$.ajaxSetup({ beforeSend : function(xhr, settings){ 

  // just because the auth_token is a private information
  if(!settings.crossDomain) {

    // parse data object
    var dataobj = JSON.parse(xhr.data);

    // add authentication token to the data object
    dataobj.auth_token = AUTHENTICATION_TOKEN;

    // save the dataobject into the jqXHR object
    xhr.data = JSON.stringify(dataobj); 

  }
}});

Another approach may be to write that token into the header and process it on the server side:

// thats not beautiful
$.ajaxSetup({ headers : { "auth_token" : AUTHENTICATION_TOKEN } });
like image 15
abstraktor Avatar answered Nov 12 '22 02:11

abstraktor


Create a function like this that will send it any time an ajax request is sent to the server

$(function(){
    $(document).ajaxSend(function(e, xhr, options) {
        var token = $("meta[name='csrf-token']").attr("content");
        xhr.setRequestHeader("X-CSRF-Token", token);
    });
})
like image 1
Leahcim Avatar answered Nov 12 '22 01:11

Leahcim