add request header on backbone

44,237

Solution 1

Models in Backbone retrieve, update, and destroy data using the methods fetch, save, and destroy. These methods delegate the actual request portion to Backbone.sync. Under the hood, all Backbone.sync is doing is creating an ajax request using jQuery. In order to incorporate your Basic HTTP authentication you have a couple of options.

fetch, save, and destroy all accept an additional parameter [options]. These [options] are simply a dictionary of jQuery request options that get included into jQuery ajax call that is made. This means you can easily define a simple method which appends the authentication:

sendAuthentication = function (xhr) {
  var user = "myusername";// your actual username
  var pass = "mypassword";// your actual password
  var token = user.concat(":", pass);
  xhr.setRequestHeader('Authorization', ("Basic ".concat(btoa(token))));
}

And include it in each fetch, save, and destroy call you make. Like so:

 fetch({
  beforeSend: sendAuthentication 
 });

This can create quite a bit of repetition. Another option could be to override the Backbone.sync method, copy the original code and just include the beforeSend option into each jQuery ajax request that is made.

Hope this helps!

Solution 2

The easiest way to add request header in Backbone.js is to just pass them over to the fetch method as parameters, e.g.

MyCollection.fetch( { headers: {'Authorization' :'Basic USERNAME:PASSWORD'} } );

Solution 3

One option might be to use the jQuery ajaxSetup, All Backbone requests will eventually use the underlying jQuery ajax. The benefit of this approach is that you only have to add it one place.

$.ajaxSetup({
    headers: { 'Authorization' :'Basic USERNAME:PASSWORD' }
});

Edit 2nd Jan 2018 For complex web applications this may not be the best approach, see comments below. Leaving the answer here for references sake.

Solution 4

You could override Backbone sync method.

#coffeescript
_sync = Backbone.sync
Backbone.sync = (method, model, options) ->
    options.beforeSend = (xhr) ->
        xhr.setRequestHeader('X-Auth-Token_or_other_header' , your_hash_key)
        #make sure your server accepts X-Auth-Token_or_other_header!!
    #calling the original sync function so we only overriding what we need
    _sync.call( this, method, model, options )       

Solution 5

Backbone.$.ajaxSetup({
    headers: {'Authorization' :'Basic USERNAME:PASSWORD'}
});

This code set headers to Backbone ajax, so they will be sent with every Backbone.sync. You will be able to send headers without using xhr.setRequestHeader with every sync call.

So you don't need to do the following every time:

MyCollection.fetch({ headers: {'Authorization' :'Basic USERNAME:PASSWORD'} } );

You can just do

MyCollection.fetch();

Maybe it's kind of hack but it works perfectly for my system.

Share:
44,237
n0minal
Author by

n0minal

Updated on July 09, 2022

Comments

  • n0minal
    n0minal almost 2 years

    My server has a manual authorization. I need to put the username/password of my server to my backbone request inorder for it to go through. How may i do this? Any ideas? Thank you

  • n0minal
    n0minal about 12 years
    tried your code. but there's no response. it doesn't call the service.
  • shanewwarren
    shanewwarren about 12 years
    No response at all? Or are you receiving a 401 response code?
  • n0minal
    n0minal about 12 years
    nope. anyways. can you give me a sample code on how to override the backbone.sync to headers?
  • MusikPolice
    MusikPolice about 11 years
    Can you provide an example of the backbone.js code that you wrote for this implementation? I'm having a problem getting it to work. You can see my progress in this question
  • albertpeiro
    albertpeiro almost 11 years
    This worked for me, surprisingly! And it's not in the docs by the time I'm typing just if anyone wondered. Extremely simple way to handle it ;) amazing. >thanks!
  • dstarh
    dstarh over 10 years
    that works unless username has a : in it, you really should base64 encode username:password
  • chug2k
    chug2k over 10 years
    I wouldn't copy the original Backbone.sync method. You can do something like what's suggested in japhr.blogspot.com/2011/10/…, but basically just override options, and call Backbone.Model.prototype.fetch.call(this, options).
  • Wally Altman
    Wally Altman almost 9 years
    Perhaps you could give an explanation as to how this answers the question?
  • Cristian C.
    Cristian C. about 8 years
    I like your solution! But in the return line I would call Backbone.Model.prototype.sync.apply(this, arguments) instead.
  • sebastian-greco
    sebastian-greco about 8 years
    @cristian-conedera You are right, that would be a more elegant and correct way. Changed the code as you suggested
  • Emile Bergeron
    Emile Bergeron almost 8 years
    I would just add a call to the original beforeSend option (if passed) inside the new beforeSend callback. See the annotated source for reference: backbonejs.org/docs/backbone.html#section-179
  • Emile Bergeron
    Emile Bergeron over 6 years
    While it looks like it could work, don't use this for the reasons I described in another answer.
  • Emile Bergeron
    Emile Bergeron over 6 years
    It is a hack that shouldn't be used for reasons explained in another answer of mine. It's also the same answer as the $.ajaxSetup one above.
  • Emile Bergeron
    Emile Bergeron over 6 years
    That's a good way, but instead of overwriting the sync function, you should override it and call the parent one which is not guaranteed to be Backbone.sync.
  • Emile Bergeron
    Emile Bergeron over 6 years
    That's the same answer as the fetch example above, but without any explanation.
  • Andy Polhill
    Andy Polhill over 6 years
    I'd be inclined to agree, my answer is pretty old now. The only thing I would say is if you are working on a simple experiment with one data source this would be a quick way of getting going. So I might leave it here for reference.
  • Ziko
    Ziko over 4 years
    Is there a way to define the response interceptor? Something like ajaxError?