simple web Engineering

April 24 2014

Ember.SimpleAuth needs a logo!

Every good open source project needs a nice and shiny logo these days. It would be great if Ember.SimpleAuth had one as well. As I’m not really an expert in these things it would be great if some of the more artistic advanced contributors/followers could contribute something!

April 10 2014

Ember.SimpleAuth 0.3.0

Ember.SimpleAuth 0.3.0 was just released. The main change in this release is the split of Ember.SimpleAuth into one core library and a set of extension libraries. These extension libraries include everything that’s not mandatorily required for Ember.SimpleAuth like authenticators, stores etc. so that every application would only have to load whatever it needs. These extension libraries are:

  • ember-simple-auth-oauth2: includes the OAuth 2.0 authenticator and authorizer which are just one option out of many and probably not needed in many projects (e.g. when using a custom authenticator)
  • ember-simple-auth-devise: new authenticator/authorizer package that is compatible with the Ruby gem devise.
  • ember-simple-auth-cookie-store: The cookie store which is probably only used in few projects.

There are hopefully more extension libraries to come as people start to provide more authenticators, authorizers and other components and now there’s a (more or less, pre 1.0) stable API for these libraries as well as a set of tasks to build and test them

Another bigger change in this release is that having an authorizer is now optional. As there are applications that are purely client side and don’t use a server backend expecting every application to use an authorizer was probably not so great in the first place. However, applications that do use an authorizer can simply configure one in Ember.SimpleAuth’s setup method and everything will behave as before:

Ember.Application.initializer({
  name: 'authentication',
  initialize: function(container, application) {
    Ember.SimpleAuth.setup(container, application, {
      authorizerFactory: 'authorizer:oauth2-bearer'
    });
  }
});

For more information about this release see the release notes at: https://github.com/simplabs/ember-simple-auth/releases/tag/0.3.0

April 6 2014

Ember.SimpleAuth 0.2.1

Ember.SimpleAuth 0.2.1 was released with some minor improvements: https://github.com/simplabs/ember-simple-auth/releases/tag/0.2.1

March 21 2014

Introduction to Ember.SimpleAuth - talk I gave at the Ember.js Munich Meetup in March 2014. The slides are available here.

March 11 2014

Ember.SimpleAuth 0.2.0

Ember.SimpleAuth was released with a completely rebuilt build and testing infrastructure as well as some important bug fixes. Find the complete release notes on github.

January 20 2014

Ember.SimpleAuth 0.1.0

Since Ember.SimpleAuth was released in October 2013, there were lots of issues reported, pull requests submitted and merged etc. Now all this feedback together with some fundamental design improvements results in the release of the 0.1.0 version of Ember.SimpleAuth. This is hopefully paving the way for a soon-to-be-released version 1.0.

What changed?

The most significant change is the extraction of everything specific to specific authentication/authorization mechanisms (e.g. the default OAuth 2.0 implementation) into strategy classes which significantly improves customizability and extensibility. Instead of having to override parts of the library, using e.g. a custom authentication method is now as simple as specifying the class in the respective controller:

App.LoginController = Ember.Controller.extend(Ember.SimpleAuth.LoginControllerMixin, {
  authenticator: App.CustomAuthenticator
});

This makes implementations cleaner and also helps defining the public API that Ember.SimpleAuth will settle on in the long term.

Other changes include the introduction of store strategies (Ember.SimpleAuth comes with a cookie store that is equivalent to the old store, a store that uses the browser’s localStorage API and which is the new default as well as an in-memory store which is mainly useful for testing) as well as error handling/token invalidation, added callback actions like sessionInvalidationSucceeded etc. See the README and the API docs for complete documentation.

Upgrading

Upgrading will be pretty straight forward in most cases. The main change that could bite you is probably the change in Ember.SimpleAuth.setup's signature. While it used to expect the container as well as the application instance, the container argument was dropped as it wasn’t actually needed. So in the initializer, change this:

Ember.Application.initializer({
  name: 'authentication',
  initialize: function(container, application) {
    Ember.SimpleAuth.setup(container, application);
  });
});

to this:

Ember.Application.initializer({
  name: 'authentication',
  initialize: function(container, application) {
    Ember.SimpleAuth.setup(application);
  });
});

Also, as the login and logout actions in ApplicationRouteMixin were renamed to authenticateSession and invalidateSession, in your templates change this:

{{#if session.isAuthenticated}}
  <a {{ action="logout" }}>Logout</a>
{{else}}
  <a {{ action="login" }}>Login</a>
{{/if}}

to this:

{{#if session.isAuthenticated}}
  <a {{ action="invalidateSession" }}>Logout</a>
{{else}}
  <a {{ action="authenticateSession" }}>Login</a>
{{/if}}

Also the LoginControllerMixin's login action was renamed to authenticate so in your login template change this:

<form {{action login on='submit'}}>

to this:

<form {{action authenticate on='submit'}}>

These are really the only changes needed if your application is using Ember.SimpleAuth’s default settings, the default OAuth 2.0 mechanism etc. For other scenarios, see the README, API docs and also the examples provided in the repository.

Outlook

I hope that this release can pave the way towards a stable API for Ember.SimpleAuth. It would also be great of course if many people came up with authenticator and authorizer implementations for all kinds of backends to prove the design of Ember.SimpleAuth’s strategy approach as well as to build a library of ready-to-use strategies for the most common setups.

October 28 2013

Ember.SimpleAuth implements RFC 6749 (OAuth 2.0)

Update: Ember.SimpleAuth 0.1.0 has been released! The information in this is (partially) outdated.

With the release of Ember.SimpleAuth 0.0.4 the library is compliant with OAuth 2.0 - specifically it implements the "Resource Owner Password Credentials Grant Type" as defined in RFC 6749 (thanks adamlc for the suggestion). While this is only a minor change in terms of functionality and data flow, used headers etc. it makes everyone’s life a lot easier as instead of implementing your own server endpoints you can now utilize one of several OAuth 2.0 middlewares that already implement the spec.

With the OAuth 2.0 support also comes support for access token expiration and refresh tokens. Using expiring access tokens improves overall security as replay attacks are less likely while with refresh tokens Ember.SimpleAuth can automatically obtain new access tokens before they expire so that the user doesn’t recognize the token actually changes.

Other changes

Other smaller additions include support for external OAuth/OpenID providers and manipulation of the request used to obtain the access token. Also the API was simplified and the login and logout actions were moved to the ApplicationControllerMixin and the /logout route has been removed. The new API now looks like this:

Ember.Application.initializer({
  name: 'authentication',
  initialize: function(container, application) {
    Ember.SimpleAuth.setup(container, application);
  }
});
 
App.Router.map(function() {
  this.route('login');
  this.route('protected');
});
 
App.ApplicationRoute = Ember.Route.extend(Ember.SimpleAuth.ApplicationRouteMixin);
App.LoginController  = Ember.Controller.extend(Ember.SimpleAuth.LoginControllerMixin);

Future plans

Currently I’m working on adding API documentation within the source together with a means of generating some nice HTML out of that. I don’t currently see that there is much else missing in the library so I’d like to release a 1.0.0 version soon. Of course I’d like to make sure that Ember.SimpleAuth is actually being used and working so please submit bug reports, patches etc. or provide general feedback/ideas!

October 9 2013

Ember.SimpleAuth

Update: Ember.SimpleAuth 0.1.0 has been released! The information in this is (partially) outdated.

After I wrote 2 blog posts on implementing token based authentication in Ember.js applications and got quite some feedback, good suggestions etc., I thought it would be nice to pack all these ideas in an Ember.js plugin so everybody could easily integrate that into their applications. Now I finally managed to release version 0.0.1 of that plugin: Ember.SimpleAuth.

Instead of providing a heavyweight out-of-the-box solution with predefined routes, controllers etc., Ember.SimpleAuth defines lightweight mixins that the application code implements. It also does not dictate anything with respect to application structure, routing etc. However, setting up Ember.SimpleAuth is very straight forward and it can be completely customized. The requirements on the server interface are minimal (see the README for more information on the server side).

Using Ember.SimpleAuth

Using Ember.SimpleAuth in an application only requires a few simple steps. First, it must be enabled which is best done in a custom initializer:

Ember.Application.initializer({
  name: 'authentication',
  initialize: function(container, application) {
    Ember.SimpleAuth.setup(application);
  }
});

The second step is to setup the routes for logging in and out:

App.Router.map(function() {
  this.route('login');
  this.route('logout');
});

Then, the generated controller and route must implement the mixins provided by Ember.SimpleAuth:

App.LoginController = Ember.Controller.extend(Ember.SimpleAuth.LoginControllerMixin);
App.LogoutRoute     = Ember.Route.extend(Ember.SimpleAuth.LogoutRouteMixin);

Of course the application also needs a template that renders the login form:

<form {{action login on='submit'}}>
  <label for="identification">Login</label>
  {{view Ember.TextField id='identification' valueBinding='identification' placeholder='Enter Login'}}
  <label for="password">Password</label>
  {{view Ember.TextField id='password' type='password' valueBinding='password' placeholder='Enter Password'}}
  <button type="submit">Login</button>
</form>

At this point, everything that’s necessary for users to log in and out is set up. Also, every AJAX request (unless it’s a cross domain request) that the application makes will send the authentication token that is obtained when the user logs in. To actually protect routes so that they are only accessible for authenticated users, simply implement the respective Ember.SimpleAuth mixin in the route classes:

App.ProtectedRoute = Ember.Route.extend(Ember.SimpleAuth.AuthenticatedRouteMixin);

More

There is more documentation as well as examples in the repository on github. Also the code base is quite small so I suggest to read through it to better understand what’s going on internally.

Patches, bug reports etc. are highly appreciated of course - get started by forking the project on github!

August 8 2013

(better) Authentication in ember.js

Update:I released an Ember.js plugin that makes it very easy to implement an authentication system as described in this post: Ember.SimpleAuth.

When we started our first ember.js project in June 2013, one of the first things we implemented was authentication. Now, almost 2 months later, it has become clear that our initial approach was not really the best and had some shortcomings. So I implemented a better authentication (mostly based on the embercasts on authentication).

I’m using the latest (as of early August 2013) ember.js and handlebars releases in this example.

Update:I changed the section on actually using the token to use $.ajaxPrefilter instead of a custom ember-data adapter (thanks to Marc for the comment!)

The basics

The basic approach is still the same as in our initial implementation - we have a /session route in our Rails app that the client POSTs its credentials to and if those are valid gets back an authentication token together with an id that identifies the user’s account on the server side.

This data is stored in a "session" object on the client side (while technically there is no session in this stateless authentication mechanism, I still call it session in absence of an idea for a better name). The authentication token is then sent in a header with every request the client makes.

The client "session"

The "session" object on the client side is a plain Ember.Object that simply keeps the data that is received from the server on session creation. It also stores the authentication token and the user’s account ID in cookies so the user doesn’t have to login again after a page reload (As Ed points out in a comment on the old post it’s a security issue to store the authentication token in a cookie without the user’s permission - I think using a session cookie like I do should be ok as it’s deleted when the browser window is closed. Of course you could also use sth. like localStorage like Marc points out below). I’m creating this object in an initializer so I can be sure it exists (of course it might be empty) when the application starts.

When this has run I can always access the current "session" information as App.Session. Notice the .create() at the end of the initializer that creates an instance of the Ember.Object right away. When we need to check whether a user is authenticated we can simply check for presence of the authToken property. Of course we could add a isAuthenticated() method that could perform additional checks but we didn’t have the need for that yet.

This "session" object will also load the actual account record from the server if the authAccountId is set (this.set('authAccount', App.Account.find(authAccountId));. This allows us to e.g. use App.Session.authAccount.fullName in our templates to display the user’s name or similar data.)

To actually use the authToken when making server requests, we register an AJAX prefilter that adds the authentication token in a header as long as the request is sent to our domain:

The Rails server can then find the authenticated user by the token in the header:

Logging in

As described above, the login API is a simple /session route on the server side that accepts the user’s login and password and responds with either HTTP status 401 when the credentials are invalid or a session JSON when the authentication was successful. On the client side we have routes for creating and destroying the session:

The SessionNewController only needs one action login that sends the entered credentials and acts according to the server’s response - if the server responds successfully it reads the session data from the response and updates the App.Session object accordingly. It also checks whether there is an attempted transition that was intercepted due to missing authentication and retries that if it exists (This is the case where the user tries to access a certain page without having authenticated, is redirected to the login form, logs in and is redirected again to the initially requested page).

Notice that we do not handle the error case here. To have a better user experience you would probably want to define a .fail handler as well that display an error message.

The template is just a simple form (actual elements, classes etc. of course depend on your specific application:)

Logging out

Logging out is actually pretty simple as well. The client just sends a DELETE to the same /session route that makes the server reset the authentication token in the database so that the token on the client side is invalidated. The client also deletes the saved session information in App.Session so there’s no stale data.

As this action should be triggered as soon as the user enters the /#/session/destroy route, we have a simple route implementation that triggers the action upon route activation:

Authenticated routes

To easily enable authentication for any route in the application, I created an App.AuthenticatedRoute that extends Ember.Route and that all routes that need to enforce user authentication can extend again:

Notice that redirectToLogin sets the attemptedTransition of App.Session so that the user will be redirected to the initially requested page after successfulyl logging in.

This is better authentication with ember.js - enjoy!

July 30 2013

"Mir persönlich wäre es am liebsten, wir machten mit unseren Mitstreitern in Deutschland ein eigenes Google auf", sagte Oliver Stock, Chefredakteur von Handelsblatt Online, zu Süddeutsche.de.

June 29 2013

excellent 2.0.0

I just released excellent 2.0.0 which has some big improvements:

  • now supporting config file .excellent.yml in current working directory to configure which specs to run/ not to run with thresholds, patterns etc.
  • predefined globals will not be reported anymore ($!, $@, $&, $`, $’, $+, $1, $2.., $~, $=, $/, $, $„ $;, $., $, $_, $0, $*, $$, $?, $:, $”, $DEBUG, $FILENAME, $LOAD_PATH, $stdin, $stdout, $stderr, $VERBOSE, $-0, $-a, $-d, $-F, $-i, $-I, $-l, $-p, $-v)
  • enabled previously disable checks again: AbcMetricMethodCheck, ControlCouplingCheck, CyclomaticComplexityBlockCheck, CyclomaticComplexityMethodCheck, ForLoopCheck, FlogBlockCheck, FlogClassCheck, FlogMethodCheck
  • testing now uses Rspec 2
  • internal cleanups/ simplifications

June 27 2013

excellent 1.7.2

I just released excellent 1.7.2 which includes the following fixes:

June 15 2013

Authentication in ember.js

Update:I released an Ember.js plugin that makes it very easy to implement an authentication system as described in this post: Ember.SimpleAuth.

Update: After I wrote this I found out that it’s actually not the best approach to implement authentication in Ember.js… There are some things missing and some other things can be done in a much simpler way. I wrote a summary of the (better) authentication mechanism we moved to.

I’m using the latest (as of mid June 2013) ember/ember-data/handlebars code directly from the respective github repositories in this example.

When we started our first project with ember.js, the first thing we came across was how to implement authentication. While all of us had implemented authentication in “normal” Rails apps several times we initially weren’t sure how to do it in ember.js. Also information on the internet was scarce and hard to find.

The only more elaborate sample project I found was the ember-auth plugin. While that seemed to be very complete and high quality it is also very heavy weight and I didn’t want to add such a big thing to our codebase only to implement simple authentication into our app. So I rolled my own implementation.

The basics

The general route to go with authentication in ember.js is to use token based authentication where the client submits the regular username/password credentials to the server once and if those are valid receives an authentication token in response. That token is then sent along with every request the client makes to the server. Having understood this the first thing to do is to implement a regular login form with username and password fields:

That template is backed by a route that handles the submission event and posts the data to the /session route on the server - which then responds with either status 401 or 200 and a JSON containing the authentication token and the id of the authenticated user:

I’m using a route instead of a controller here as redirecting should only be done from routes and not controllers. See e.g. this SO post for more info.

The response JSON from the server would look somehow like this in the successful login case:

At this point the client has the authentication data necessary to authenticate itself against the server. As tat authentication data would be lost every time the application on the client reloads and we don’t want to force a new login every time the user reloads the page we can simply store that data in a cookie (of course you could use local storage etc.):

Making authenticated requests

The next step is to actually send the authentication token to the server. As the only point point of interaction between client and server in an ember.js app is when the store adapter reads or writes data, the token has to be integrated in that adapter somehow. As there’s not (yet) any out-off-the-box support for authentication in the DS.RESTAdapter, I simply added it myself:

Now the adapter will pass along the authentication token with every request to the server. One thing that should be made sure though is that whenever the adapter sees a 401 response which would mean that for some reason the authentication token became invalid, the session data on the client is deleted and we require a fresh login:

Enforcing authentication on the client

Now that the general authentication mechanism is in place it would be cool to have a way of enforcing authentication on the client for specific routes so the user never gets to see any pages that they aren’t allowed to. This can be done by simply introducing a custom route class that will check for the presence of a session and if none is present redirects to the login screen. Any other routes that require authentication can then inherit from that one instead if the regular Ember.Route

This is actually very similar to the concept of an AuthController in Rails with a before_filter that enforces authentication:

Cleanup

As the code is now spread up into a number of files and classes, I added a Session model:

alongside an App.AuthManager accompanied by a custom initializer to clean it up:

This is simple authentication with ember.js!

May 22 2013

😘😍😘😍😘😍😘😍😘😍😘😍😘😍😘😍😘😍😘😍😘

😘😍😘😍😘😍😘😍😘😍😘😍😘😍😘😍😘😍😘😍😘

May 20 2013