I am consuming an API which returns no cookie on login,but only an auth_token as part of json response.
The base URL delivers the backbonejs application. say http://www.webiyo.com/ and by default login page is displayed.
I want to keep the user session even if the user refreshes the page in backbonejs app.
Problem is that my API doesn't return session cookie aka auth_token cookie ( it just returns an auth_token in a response json which is needed to be passed on all the subsequent calls in the query string )
So in such situation could I set a javascript cookie on my own to track user session at browser side using backbonejs ? if yes how ?
I have been referring
http://whatcodecraves.com/articles/2012/01/11/backbonejs-sessions-and-authentication but it assumes the http cookie "auth_token" is sent directly from the server to browser on login success unlike my case where the the "auth_token" is the part of the json response on logn success.
Based on what you've described, storing the auth_token
in browser's session cookie seems to be the way to go.
Backbone.js doesn't support cookie manipulation. However, you can use a jQuery plugin/write your own cookie manipulator to handle this.
Assuming you're using jquery-cookie
(https://github.com/carhartl/jquery-cookie), here's an example on how you can achieve this (It's on their Wiki too!):
$.cookie('auth_token', authTokenValue);
For the API you interact with, depends on how they accept the auth_token
, you may need to create a BaseModel on top of Backbone.Model to handle the use of auth_token
automatically.
For example, if the API expects you to pass the auth_token
as a part of QueryString, you'll need to override Backbone.Model.url()
function:
var BaseModel = Backbone.Model.extend({
url: function() {
var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError();
if (this.isNew()) return base + '?' + $.cookie('auth_token');
return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id) + '?' + $.cookie('auth_token');
}
});
var EntityModel = BaseModel.extend({ ... });
So, how you override the Backbone.Model depends on what the API endpoint expects.
If following this is what your ultimate goal is, there are couple things you can do:
App.Models.Session = Backbone.Model.extend
defaults:
access_token: null,
user_id: null
initialize: ->
@load()
authenticated: ->
Boolean(@get("auth_token"))
login: (email, password, options)->
# make an AJAX call to the authentication API
# once returned, call @save(...) with auth_token that you got back.
# options is there to facilitate that, if you want to pass in an onAuthencated or onNotAuthenticated callbacks, you can.
# Saves session information to cookie
save: (auth_token)->
$.cookie('auth_token', auth_token)
# Loads session information from cookie
load: ->
@set
access_token: $.cookie('auth_token')
App.start = ->
@session = new App.Models.Session()
if @session.authenticated()
# redirect to user page
else
# launch a login form
# call @session.login(email, password)
As a side note, instead of using the option
param in @login(email, password, options), you can also trigger an event, like @trigger('authenticated')
from the model, letting the View/App knows that the user is now authenticated.