Series: User Auth

Authenticated Routes

Published on Oct 23, 2015

Some pages are only for your logged-in users, and you want to protect those routes.

This video shows you not only how to protect your authenticated routes, but also how to direct users back to that route once they’ve signed in.


Links

Code

mixins/authenticated-route.js

import Ember from 'ember';

export default Ember.Mixin.create({
  session: Ember.inject.service(),
  beforeModel(transition){
    if(!this.get('session.currentUser')){
      var loginController = this.controllerFor('users');
      loginController.set('previousTransition', transition);
      this.transitionTo('users')
    }
  }
});

Mixing it into a route:

import Authenticated from '../mixins/authenticated-route';

export default Ember.Route.extend(Authenticated, {
  //...
})

Controller for login page:

export default Ember.Controller.extend({
  session: Ember.inject.service(),
  actions: {
    login(user){
      this.get("session").login(user)
      var previousTransition = this.get('previousTransition');
      if (previousTransition) {
        this.set('previousTransition', null);
        previousTransition.retry();
      } else {
        // Default back to homepage
        this.transitionToRoute('index');
      }
    }
  }
})

Transcript

In the last few episodes we’ve been working with the session service, and working around user authentication authorization. In this episode, we’re going to be exploring authenticated routes.

So as you can see, we can go to this authenticated route when we’re logged in,

but if we log out,

then when we hit this

it’ll take us to the login route.

And then when we log in, it will take us to the authenticated route where we were wanting to go before.

So how do we build that? We’ll start with what we had last time, and then we’ll generate a route called authenticated that will give us our route in our template and add that to the router.

We’ll paste in some text from the authenticated route and then here in our application for a header, we’ll have a link.

So we can go here, we can hit this,

and it’ll take us to the authenticated route.

However, if we’re logged out, it’ll still let us go to the authenticated route.

We want to block users who aren’t signed in from visiting this page. We’ll do this in the authenticated route. So first we’ll inject the session service and then we’ll use the beforeModel hook. So beforeModel is run, well, before the model, but also important for our purposes before anything is displayed on the page. So it’ll check, we’ll check, to see if the currentUser is on the session, and if it’s not then we’ll transition to the users route. If you’re doing this you might transition to the login route, but we haven’t made a specific one of that yet.

So now you’ll see that if we try to go to the authenticated route when we’re not logged in,

it’ll redirect us to the users route, like we expect.

But if we’re logged in, then it works.

So right now it works, but currently it redirects them to the monsters route after every time they sign in, but if they got redirected to the users login route right after trying to go to the authenticated route, then they’re going to want to go back to the authenticated route and not to the monsters route.

How can we set this up? Our first step will be in the authenticated route where we’re doing the redirection. So the beforeModel hook, it has some arguments, and the first one of those arguments is the transition. So what we can do is we’ll get the loginController using controllerFor, and then we’ll set the property previousTransition to the transition that’s happening as we’re going through this beforeModel hook, so it’ll remember that it’s trying to go the authenticated route.

Then in the users controller which we’re having double as the login controller for now, we’re going to grab that previousTransition, and then if that transition is available, then first we’re going to set it to null so we don’t accidentally do it again next time that we log in, and then we’re going to retry that transition.

So what that’ll do is if we come from the authenticated route,

it’ll send us back to the authenticated route.

So what happens if we want to make more routes authenticated? One solution is just to copy all of this

and paste it in somewhere else. So if we want to make the monsters route authenticated, we could just paste it in like that.

However, a mixin seems a much better choice. So let’s generate our mixin,

and then we can copy this code into the mixin, and so we’ll have this code exactly once.

That means in the authenticated route, we can delete all of this code,

and we’ll replace that by importing the mixin and using it.

Then we can do the same thing for the monsters route.

Of course we’ll still be leaving in the model.

So now to make a route authenticated, we only have to import the mixin and include it.

Let’s see this in action. So of course we can go to the monsters route, we can go to the authenticated route just fine.

But when we log out, then we’ll try to go to the monsters route.

It redirects us to the users route.

We log in, it takes us to the monsters route.

Then if we repeat the process with the authenticated route, we see it works there as well.

So even though the code is completely generic, it still has the correct redirection behavior.

So that’s authenticated routes. One thing to note before we leave is that these aren’t completely secure even if we had more than just a login button. If we had password protection, this still wouldn’t completely protect your pages. The reason for that is because you can easily go into the services, go into the container, and just edit it.

So make sure to protect your stuff at the level of the server as well, and we’ll show you how to do that next week. I’ll see you then.

User Auth

Subscribe to our mailing list