Don't Panic!

Sam Vary's blog about programming and life in general.

Using Ember Simple Auth to Add Sessions to Your Ember App

I think my blog could do with a bit of focus for my next entry, so I decided to pick a more technical topic and hone in on something that was giving me trouble. I’ve found Ember to be very challenging, but what’s something more specific I’d like to understand better? Hmm, I thought to myself, I wonder how authentication usually goes down in Ember. That might be worth exploring.

The first thing I came across was a library called Ember Simple Auth, which allows you to do just what I wanted - implement a lightweight authentication system within your already existing Ember app.

“That’s cool” you say, “but how does it work?” Well, Skip, I’m glad you asked. There are 4 key building blocks that come with Ember Simple Auth, once you install the library. You can also go clone a repo that contains a dummy app for easy reference with all the needed functionality already built-out, which is pretty thoughtful, and the dummy app includes an example for Facebook integration as well.

So the building blocks roll out thusly: the session itself, a session store, authenticators, and authorizers.

“What do those things do?” you ask, staring at me wide-eyed.

Pretty simple, the session is as we generally understand it and is the main interface to the library. The session in the context of Ember Simple Auth contains all the methods for authenticating the session.

The session store makes sure that the session state of the current user is persistent, so that nothing gets screwed up if you hard (or soft) refresh the page. It also provides the functionality of synchronizing the session across multiple tabs and pages, so that a user is logged in no matter where they are in their browser or on the site.

Authenticators also authenticate the session, but they can support multiple ways of doing so, such as through Facebook, against the site’s own server, etc.

Authorizers take the data that is stored in a current session and generate more authorization data, which gets used in outgoing requests such as Ember Data requests, like what we saw with the Ember dynamic segments lab, for instance.

So, to install just run:

ember install ember-simple-auth

inside your app.

Once you do that, the usage is (on the surface) fairly simple. You can add this code to the application controller (app/controllers/application.js):

1
2
3
4
5
6
7
import Ember from 'ember';

export default Ember.Controller.extend({
  session: Ember.inject.service('session')

  
});

Once we do that, we can set up some conditional logic in our template (i.e. application.hbs) to query the isAuthenticated property, like so:

(handlebars code snippet for logic in the template)

Since we have that, we need to configure the action for invalidateSession back where we started in our application controller. This action will be responsible for invalidating the session and logging the user out:

1
2
3
4
5
6
7
8
9
10
11
12
13
import Ember from 'ember';

export default Ember.Controller.extend({
  session: Ember.inject.service('session'),

  

  actions: {
    invalidateSession() {
      this.get('session').invalidate();
    }
  }
});

To actually authenticate the session, we can extend one of the authenticators that the library comes with, for example OmniAuth. This gets configured when we add a file to app/authenticators:

1
2
3
4
// app/authenticators/oauth2.js
import OAuth2PasswordGrant from 'ember-simple-auth/authenticators/oauth2-password-grant';

export default OAuth2PasswordGrant.extend();

Then we build a login form…

And then the actual authentication of the login will be handled in a login controller, here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// app/controllers/login.js
import Ember from 'ember';

export default Ember.Controller.extend({
  session: Ember.inject.service('session'),

  actions: {
    authenticate() {
      let { identification, password } = this.getProperties('identification', 'password');
      this.get('session').authenticate('authenticator:oauth2', identification, password).catch((reason) => {
        this.set('errorMessage', reason.error || reason);
      });
    }
  }
});

At this point, we pretty much just need to decide which routes are restricted to users only, so we go to any routes that only a user should be able to access and add the AuthenticatedRouteMixin to that route’s .js file:

1
2
3
4
5
//app/routes/users-only.js
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin);

We would need to do this for any route that is not accessible to non-logged in users. This code will then make it so the app redirects the user to a login page whenever they attempt to access the route with an unauthenticated session.

I’ll leave this blog post as a to be continued and plan to implement this in my own Ember app a little later this week, and write a follow up post about that. There is a lot more information on the library’s github page, and much more that you can do such as with authorizing outgoing API requests with an authorizer. To be continued!