Search code examples
backbone.jsroutes

Backbone.js force to login route


I'm developing an application where my user needs to login, in this sense logging in is slightly different as the user isn't registered per say. They enter their name, and room name then they connect. The room itself contains all of the settings required for the users such as;

  • Room name
  • View settings - allowing options to be on or off
  • etc...

So what I'm looking to do is hook on to the route event, so I can force the user to go to the /login root if they're not logged in.

Surely there must be a DRY way of doing this without adding a conditional to each route?


Solution

  • The only option that comes to my mind is to overwrite the current Router.route -function, currently it looks like this:

    route: function(route, name, callback) {
      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
      if (!callback) callback = this[name]; // this is of interest
      Backbone.history.route(route, _.bind(function(fragment) {
        var args = this._extractParameters(route, fragment);
        callback && callback.apply(this, args);
        this.trigger.apply(this, ['route:' + name].concat(args));
        Backbone.history.trigger('route', this, name, args);
      }, this));
      return this;
    },
    

    What you want to do is to wrap each and every callback with a function that checks if the condition you want is met and then either calls the wrappee or reroutes to login. Underscore's wrap -function is useful here.

    route: function(route, name, callback) {
      ... // same as above
      if (!callback) callback = this[name];
      _.wrap(callback, function(cb) {
        if (userIsLoggedIn()) {
          cb();
        } else {
          this.navigate("url/to/login");
        }
      });
      ... // same as above
    },
    

    of course you have to add a check for the actual login route so that you don't create an infinite loop!

    EDIT:

    You don't have to modify the source, the most simple way to do this is:

    var CustomRouter = Router.extend({
      route: function() {
        // your overwrite here
      }
    });
    

    Use this over the one in the comments as it is native to Backbone!

    Hope this helps