Working on my first EmberJS app. The entire app requires that a user be logged in. I\'m trying to wrap my head around the best way to enforce that a user is logged in now (when
Please also take a look at : http://www.embercasts.com/
There are two screencasts there about authentication.
Thanks.
If you need to perform a check before initial state transition, there is a special function on the Ember.Application
class called deferReadiness()
. The comment from the source code:
By default, the router will begin trying to translate the current URL into application state once the browser emits the
DOMContentReady
event. If you need to defer routing, you can call the application'sdeferReadiness()
method. Once routing can begin, call theadvanceReadiness()
method.
Note that at the time of writing this function is available only in ember-latest
I put together a super simple package to manage session and auth called Ember.Session https://github.com/andrewreedy/ember-session
In terms of rechecking authentication between route transitions, you can add hooks to the enter
and exit
methods of Ember.Route
:
var redirectToLogin = function(router){
// Do your login check here.
if (!App.loggedIn) {
Ember.run.next(this, function(){
if (router.currentState.name != "login") {
router.transitionTo('root.login');
}
})
}
};
// Define the routes.
App.Router = Ember.Router.extend({
root: Ember.Route.extend({
enter: redirectToLogin,
login: Ember.Route.Extend({
route: 'login',
exit: redirectToLogin,
connectOutlets: function(router){
router.get('applicationController').connectOutlet('login');
}
}),
....
})
});
The problem with such a solution is that Ember will actually transition to the new Route (and thus load all data, etc) before then transitioning back to your login route. So that potentially exposes bits of your app you don't want them seeing any longer. However, the reality is that all of that data is still loaded in memory and accessible via the JavaScript console, so I think this is a decent solution.
Also remember that since Ember.Route.extend returns a new object, you can create your own wrapper and then reuse it throughout your app:
App.AuthenticatedRoute = Ember.Route.extend({
enter: redirectToLogin
});
App.Router = Ember.Router.extend({
root: Ember.Route.extend({
index: App.AuthenticatedRoute.extend({
...
})
})
});
If you use the above solution then you can cherry pick exactly which routes you authenticate. You can also drop the "check if they're transitioning to the login screen" check in redirectToLogin
.