My PHP api requires a user token be submitted with every request from my front-end Backbone app to make sure the user...
- Is active
- Has permissions to access the resource
What is the easiest way to set this up in Backbone? I am guessing the only way is to overwrite Backbone.sync, but what would the code look like? CoffeeScript preferred.
EDIT
Two more things
1. I would like to redirect the user to /login
if I get a 403: Access Forbidden Error
2. I pull the user model which includes the token from localStorage when the app is bootstrapped
3. I have a baseModel and baseCollection which all models / collections come from
Authentication is a responsibility of the app.
For a Backbone app, the auth logic should be within the Backbone code and changing the global jQuery's
ajax
behavior should be avoided at all cost.Cons of
ajaxSetup
orajaxSend
From the jQuery doc on
ajaxSetup
:ajaxSend
has the same problem as mentioned above. The only advantage it has overajaxSetup
is calling a function each time, giving you more flexibility than the object based options passed toajaxSetup
.The safest way, the
AuthModel
andAuthCollection
Put the authentication logic into a base model and collection. This is the most scoped solution.
Here, you could use your already existing
BaseModel
, but I'd still favor separating theBaseModel
from theAuthModel
as you may want to create a custom model which uses your base model but also uses a different external API for example.Since the new
sync
function for the model and the collection are similar but both may have a different parent implementation, I made a simple function generator.Use the generator on both a model and a collection.
Then you're ready to use these on models and collection you're sure will need authentication. Since you were already using a base model and collection, it would be just a matter of changing the
BaseModel.extend
toAuthModel.extend
.While I know you asked for a redirect on a
403 Forbidden
response, I think it should be on a401 Unauthorized
. See 403 Forbidden vs 401 Unauthorized HTTP responsesOverriding Backbone's
sync
If you don't feel like changing all models and collections at this point, but still want to follow good practices and avoid changing the global ajax setup, overriding the
Backbone.sync
function is an easy alternative.Using our previously defined
sync
generator:Managing the local storage and the authentication
To manage the data in the local storage, check Backbone-session.
It's a nice implementation of a Backbone model which syncs with the local storage instead of a REST API. It also provides a nice interface to manage the authentication.
You could do this:
And just listen for the fail event of fetch/save method to redirect a user to
/login
Backbone uses jQuery's $.ajax, so you can use $.ajaxSetup to "set default values for future Ajax requests":
Update: an improvement to this idea (thanks to @Glen) is to use $.ajaxSend to check for the existence of a token each time before setting it in the headers of the request:
Where App.getAuthToken() is a function in your Backbone app.