Romain Caron Romain Caron - 1 month ago 22
Javascript Question

How to handle a 401 unauthorized response with Backbone?

I configure my Backbone router with different views. But on some views, I need to fetch a collection. If the user is not logged in, server returns a 401 http status.

So, I configure jQuery's global ajax settings like that:

$.ajaxSetup({
xhrFields: {
withCredentials: true
},
crossDomain: true,
error: function(jqXHR, textStatus, errorThrown) {
console.log("error ajax");
if (jqXHR.status == 401) {
console.log('error 401');
app.router.navigate('', { trigger: true });
}
}
});


But it never goes in the error callback, even if the response code is 401.

Answer

Instead of modifying the ajax options globally, I modified Backbone.sync function to handle authentication.

Backbone.sync = (function(syncFn) {
    return function(method, model, options) {
        options = options || {};

        var beforeSend = options.beforeSend,
            error = options.error;

        // Add headers
        options.beforeSend = function(xhr) {
            xhr.setRequestHeader('withCredentials', true);
            if (beforeSend) return beforeSend.apply(this, arguments);
        };

        // handle unauthorized error (401)
        options.error = function(xhr, textStatus, errorThrown) {
            console.log("error sync");
            if (error) error.call(options.context, xhr, textStatus, errorThrown);
            if (xhr.status === 401) {
                console.log('error 401');
                app.router.navigate('', { trigger: true });
            }
        };

        return syncFn.apply(this, arguments);
    };
})(Backbone.sync);