Introducing Torii: Authentication primitives for Ember apps


#1

Howdy all,

I’d like to introduce a new library we’ve just released, and get your feedback. With our partner Vestorly, @bantic and I are happy to share Torii:

http://vestorly.github.io/torii/

Torii provides your Ember application with an authorization service. So, to get an auth code from Facebook, you might do this:

// app/routes/application.js
export default Ember.Route.extend({
  actions: {
    facebookSignIn: function(){
      var controller = this.controllerFor('session');
      this.get('torii').open('facebook-oauth2').then(function(authorization){
        controller.set('authCode', authorization.code);
      });
    }
  }
});

Torii doesn’t say what you should do with authorization, it just provides you a good abstraction to write auth providers and handle their use in your app.

However, using authorization objects for managing your applications session is obviously a common use-case. With that in mind, we’ve also included a simple session wrapper. To use the session manager, you’ll need to write an adapter for your particular API.

// app/app.js

window.ENV = window.ENV || {};
window.ENV['torii'] = {
  sessionServiceName: 'session', // a 'session' property will be injected on routes and controllers
};

// Setup the Ember app

// Then load Torii
require('torii/ember');
 
export default App;
// app/torii-adapters/application.js
//
// Here we will presume the store has been injected onto torii-adapter
// factories. You would do this with an initializer, e.g.:
//
// application.inject('torii-adapter', 'store', store:main');
//
export default Ember.Object.extend({

  // The authorization argument passed in to `session.open` here is
  // the result of the `torii.open(providerName)` promise
  open: function(authorization){
    var userId = authorization.user,
        store  = this.get('store');
    return store.find('user', userId).then(function(user){
      return {
        currentUser: user
      };
    });
  }
});

Now controllers and routes have a session injection. Sessions respond to open, fetch, and close with promises. If open or fetch is successful, the session object is put into a isAuthenticated state and any properties on the object returned by the adapter are set onto it (such as currentUser).

The adapters are intentionally left entirely to you to implement.

I’ve also written a longer blog post that provides context for Torii’s role in your authentication design: http://madhatted.com/2014/6/17/authentication-for-single-page-apps

So give Torii a try and let us know what you think! PRs are very welcome.


#2

awesome work.

curious if you’ve looked at ember-simple-auth? how would this compare to that? thanks.


#3

@marcoow actually wrote up an example of how the two would work together: https://github.com/Vestorly/torii/blob/master/example/simple-auth.html He consumes a Torii provider via an Ember-Simple Auth authenticator layer. The is totally what we intend Torii to be used for. The providers are intended to be composable parts of your application.

We did decide to ship with our own very lightweight session management layer. It is opt-in (you need to set an ENV value as I do in the original post), and still leaves much of the implementation to you. Ember Simple Auth is very opinionated, and we wanted to offer something shallower, simpler, and more easy to port existing auth solutions too.

tl;dr use what you want from Torii, mash it up with Ember Simple Auth if it is appropriate for you!


#4

Great work @mixonic and @bantic! I’ll include a Torii authenticator in the next version of Ember.SimpleAuth.