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:
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.
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:
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 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:
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.
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.
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!
After I wrote 2 blogposts 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 in an application only requires a few simple steps. First, it must be enabled which is best done in a custom initializer:
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:
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:
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 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:
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!
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 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:
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:
Publisher information according to §6 Teledienstgesetz (TDG)
Responsible according to §6 MDStV: Marco Otte-Witte
Marco Otte-Witte, Fraunhoferstr. 9, 80469München, Germany
Exclusion of Liability
I check and update the information on this website constantly. Despite all accurateness, the data can change in the meantime. Liability concerning timeliness, correctness and completeness of the available information can not be assumed. This applies also for all other websites which are referred via hyperlink. I am not responsible for the content of these websites.