Skip to content Skip to sidebar Skip to footer

Save Session Parameters In Cookies

I've got a simple Backbone.js app which uses json-server as a backend. I have a function to log in, that finds a user from the collection, but I don't get how will I save my sessio

Solution 1:

Using a model to handle authentication would make more sense than a collection. Keep the model's responsibility simple and scoped to one thing. A model to handle the authentication, then a model to handle calls to other object which needs to be authenticated, not both at once.

I personally based authentication on Backbone-session's model.

// Using CommonJSvar Session = require('backbone-session');

// Extend from Session to implement your API's behaviourvar Account = Session.extend({
    urlRoot: 'http://localhost:3000/users',
    signIn: function(opt) {
        opt = opt || {};
        opt.data = _.extend({}, {
            login: opt.login,
            password: opt.password
        }, opt.data);
        return this.fetch(opt);
    },
    signOut: function(opt) { /** handle logout */ },
    getAuthStatus: function() { /** handle refetching if needed */ }
});

Which I expose as a service to my application. In this session module, I override Backbone.Sync to ensure auth for each following calls to the API for any models or collection.

var mySession = newAccount();


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

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

        // Add auth headers
        options.beforeSend = function(xhr) {
            xhr.setRequestHeader('Authorization', "Bearer " + mySession.get('authToken'));
            if (beforeSend) return beforeSend.apply(this, arguments);
        };

        // handle unauthorized error (401)
        options.error = function(xhr, textStatus, errorThrown) {
            if (error) error.call(options.context, xhr, textStatus, errorThrown);
            if (xhr.status === 401) {
                mySession.signOut();
            }
        };

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

Backbone-session's model uses the local storage as a backend. Its own sync method is overriden to use the local storage instead of the default sync behavior.

sync: function(method, model, options) {
  options = options || {};
  var url = model.options.url || model.url;
  var key = _.isFunction(url) ? url() : '' + url;
  var response;
  switch (method) {
    case'create':
    case'update':
      var data = model.toJSON();
      var text = JSON.stringify(data);
      response = localStorage.setItem(key, text);
      break;
    case'delete':
      response = localStorage.removeItem(key);
      break;
    case'read':
      response = JSON.parse(localStorage.getItem(key));
      break;
  }
  if (_.isFunction(options.success)) {
    options.success(response);
  }
  returnBackbone.$.Deferred()
    .resolve(response)
    .promise();
},

Why the local storage?

You could use this implementation and change it minimally to use cookies instead.

The local storage was a better option for me since my API is on another domain and uses CORS to enable public access. Safari has limitation on cookies.

Safari also blocks cookies from sites that haven't been visited directly. You can see in the security settings. It's default setting is Accept cookies: "Only from sites I visit".

Post a Comment for "Save Session Parameters In Cookies"