Permissions access check for all routes


#1

Hi, I write the first application at Ember, tell me please, how i can make redirect for all routes to “login” route, if user not logged? Thaks!


#2

Hmm, I think I found

var ApplicationRoute = Ember.Route.extend({
    beforeModel: function(transition) {
        if (!this.controllerFor('env').get('user')) {
            this.transitionTo('login');
        }
    }
});

#3

But it work only for first loaded route :frowning: How to make it for all routes?


#4

You can use the willTransition:

var ApplicationRoute = Ember.Route.extend({
    actions: {
        willTransition: function(transition) {
            if (!this.controllerFor('env').get('user')) {
                this.transitionTo('login');
            }
        }
    }
});

That action is called in the current route, and bubbles to the parents. So if use declare in the ApplicationRoute, you will be notified for any transition, because ApplicationRoute is the parent of all routes.


#5

Thanks, its work, but when app just been open, first route not transition


#6

Is that correct?

var ApplicationRoute = Ember.Route.extend({
 
    checkLogin: function(transition) {
        if (transition.targetName != 'auth' && !this.controllerFor('env').get('loggedIn')) {
            var loginController = this.controllerFor('auth');
            loginController.set('previousTransition', transition);
            this.transitionTo('auth');
        }
    },


    beforeModel: function(transition) {
        this.checkLogin(transition);
    },

    actions: {
        willTransition: function(transition) {
            this.checkLogin(transition);
        }
    }
});

#7

@marcioj How to restrict willTransition call when try to transition the same route.


#8

Ah you’ re right. My mistake, I forget to check the login route.

Also that embercast is a good resource for authentication.


#9

Thanks, its a good example, I have only one question:

my initializer load data asynchronously

Ember.Application.initializer({
    name: 'env',
    initialize: function(container) {
        var store = container.lookup('store:main');
        var Env = store.find('Env', 'model');
        container.lookup('controller:env').set('content', Env);
        container.typeInjection('controller', 'env', 'controller:env');
    }
});

and my route check in data when they have been loaded

var EnvController = Ember.Controller.extend({
    loggedIn: function() {
        return this.get('content.user.id');
    }.property('content.user')
});

var AuthenticatedRoute = Ember.Route.extend({
    checkLogin: function(transition) {
        if (!this.controllerFor('env').get('loggedIn')) {
            var loginController = this.controllerFor('login');
            loginController.set('previousTransition', transition);
            this.transitionTo('login');
        }
    },

    beforeModel: function(transition) {
        this.checkLogin(transition);
    },

    actions: {
        willTransition: function(transition) {
            this.checkLogin(transition);
        }
    }
});

ultimately route transited to “login” when application loaded, How can fix it?


#10

Probably your beforeModel is running before of the store.find('Env', 'model'); be loaded.

To run async code in initializers, you need to use deferReadiness and advanceReadiness

Ember.Application.initializer({
    name: 'env',
    initialize: function(container, App) {
        App.deferReadiness();
        var store = container.lookup('store:main');
        store.find('Env', 'model').then(function(Env) {
            container.lookup('controller:env').set('content', Env);
            container.typeInjection('controller', 'env', 'controller:env');
            App.advanceReadiness();
        });        
    }
});

#11

I found :smile:

Ember.Application.initializer({
    name: 'env',
    initialize: function(container) {
        var store = container.lookup('store:main');
        var Env = store.find('Env', 'model');
        App.deferReadiness();
        Env.addObserver('isLoaded', function(){
            if(Env.get('isLoaded')) {
                App.advanceReadiness();
            }
        });
        container.lookup('controller:env').set('content', Env);
        container.typeInjection('controller', 'env', 'controller:env');
    }
}); 

#12

Thanks, your way to better =)


#13

I’ve found the Ember Simple Auth plugin to be very good for authentication. It comes out-of-the-box with a mixin that allows you to easily secure all routes.

It’s still very new, so has a few rough edges when it comes to trying to do things a bit differently than what it expects, but there isn’t too much to it so it’s pretty easy to dive into the code.