Authentication is the responsibility of the application.
For a Backbone application, the auth logic should be in the Backbone code, and changing the global behavior of jQuery ajax should be avoided at all costs.
Cons of ajaxSetup or ajaxSend
From the jQuery ajaxSetup document:
Note. The settings specified here will affect all calls to $.ajax or Ajax-based derivatives such as $.get() . This can cause unwanted behavior, as other subscribers (for example, plugins) can expect the usual default settings. For this reason, we strongly recommend against using this API. Instead, set the parameters explicitly in the call or define a simple plugin for this.
ajaxSend has the same problem as mentioned above. The only advantage he has over ajaxSetup is the function call every time, which gives you more flexibility than the object-based parameters passed to ajaxSetup .
The safest way: AuthModel and AuthCollection
Put the authentication logic in the base model and collection. This is the most common solution.
Here you can use an existing BaseModel , but I would prefer to separate BaseModel from AuthModel , as you can create a custom model that uses your base model, but also uses a different external API, for example.
Since the new sync function for the model and collection is similar, but both can have a different parent implementation, I created a simple function generator.
var authSyncFunction = function(syncFn) { return function(method, model, options) { options = options || {}; var beforeSend = options.beforeSend, error = options.error; _.extend(options, {
Use a generator for both the model and the collection.
var AuthModel = BaseModel.extend({ sync: authSyncFunction(BaseModel.prototype.sync) }); var AuthCollection = BaseCollection.extend({ sync: authSyncFunction(BaseCollection.prototype.sync) });
Then you will be ready to use them on models and collections, for which you will definitely need authentication. Since you already used the base model and the collection, it would be easy to change BaseModel.extend to AuthModel.extend .
Although I know that you asked for forwarding to the 403 Forbidden answer, I think it should be at 401 Unauthorized . See 403 Forbidden vs 401 Unauthorized HTTP Responses
Override sync trunk
If you do not want to change all models and collections at the moment, but still want to follow the recommendations and avoid changing the global ajax setting, overriding the Backbone.sync function is a simple alternative.
Using our previously defined sync generator:
Backbone.sync = authSyncFunction(Backbone.sync);
Local storage and authentication management
To manage data in local storage, check Backbone-session .
This is a good implementation of the Backbone model, which synchronizes with local storage instead of the REST API. It also provides a nice interface for managing authentication.
// Extend from Session to implement your API behaviour var Account = Session.extend({ signIn: function () {}, signOut: function () {}, getAuthStatus: function () {} }); // Using the custom Account implementation var session = new Account(); session.fetch() .then(session.getAuthStatus) .then(function () { console.log('Logged in as %s', session.get('name')); }) .fail(function () { console.log('Not yet logged in!'); });