Ember.SimpleAuth's API docs are available here
Ember.SimpleAuth is a lightweight library for implementing authentication/ authorization with Ember.js applications. It has minimal requirements with respect to application structure, routes etc. With its pluggable strategies it can support all kinds of authentication and authorization mechanisms.
- it manages authentication state, synchronizes it across tabs/windows
- it authenticates users against the application server, external providers etc.
- it enforces authentication for defined routes
- it authorizes server requests
- it provides a simple customization API
Ember.SimpleAuth is built around the concept that there is always an application session in whose context the user is using the application. This session can either be authenticated or not. Ember.SimpleAuth provides a number of classes and mixins that create that session, make it available throughout the application, provide methods for authenticating and invalidating it etc.
To enable Ember.SimpleAuth in an application, simply add a custom
initializer (also see the
API docs for Ember.SimpleAuth.setup
):
Ember.Application.initializer({
name: 'authentication',
initialize: function(container, application) {
Ember.SimpleAuth.setup(container, application);
}
});
This initializer sets up the session (see the
API docs for Ember.SimpleAuth.Session
and makes it available as session
in all routes, controllers, views and
models).
The application route must include the respective mixin provided by Ember.SimpleAuth:
App.ApplicationRoute = Ember.Route.extend(Ember.SimpleAuth.ApplicationRouteMixin);
This adds actions to App.ApplicationRoute
like authenticateSession
and
invalidateSession
as well as callback actions that are triggered when the
session's authentication state changes like sessionAuthenticationSucceeded
or
sessionInvalidationSucceeded
(see the
API docs for ApplicationRouteMixin
).
Displaying e.g. login/logout buttons in the UI depending on the session's authentication state then is as easy as:
{{#if session.isAuthenticated}}
<a {{ action 'invalidateSession' }}>Logout</a>
{{else}}
<a {{ action 'authenticateSession' }}>Login</a>
{{/if}}
or in the case that the application uses a dedicated route for logging in:
{{#if session.isAuthenticated}}
<a {{ action 'invalidateSession' }}>Logout</a>
{{else}}
{{#link-to 'login'}}Login{{/link-to}}
{{/if}}
To make a route in the application require the session to be authenticated,
there is another mixin that Ember.SimpleAuth provides and that is included in
the respective route (see the
API docs for AuthenticatedRouteMixin
):
App.Router.map(function() {
this.route('protected');
});
App.ProtectedRoute = Ember.Route.extend(Ember.SimpleAuth.AuthenticatedRouteMixin);
This will make the route transition to /login
(or a different URL if
configured) when the session is not authenticated in the beforeModel
method.
Authenticators implement the concrete steps necessary to authenticate the
session. An application can have several authenticators for different kinds
of authentication mechanisms (e.g. the application's own backend server,
external authentication providers like Facebook etc.) while the session is
only authenticated with one authenticator at a time (see the
API docs for Session#authenticate
.
The authenticator to use is chosen when authentication is triggered:
this.get('session').authenticate('authenticator:custom', {});
Ember.SimpleAuth does not include any authenticators in the base library but offers extension libraries that can be loaded in the application as needed:
- ember-simple-auth-oauth2 provides an OAuth 2.0 authenticator
- ember-simple-auth-devise provides an authenticator compatible with the popular Ruby on Rails authentication plugin devise
Besides the option to use one of the predefined authenticators from the
extension libraries, it is easy to implement authenticators for custom
strategies as well. All that is necessary is to extend Authenticators.Base
and implement three methods (see the
API docs for Authenticators.Base
).
Custom authenticators have to be registered with Ember's dependency injection container so that the session can retrieve an instance, e.g.:
var CustomAuthenticator = Ember.SimpleAuth.Authenticators.Base.extend({
...
});
Ember.Application.initializer({
name: 'authentication',
initialize: function(container, application) {
container.register('authenticator:custom', CustomAuthenticator);
Ember.SimpleAuth.setup(container, application);
}
});
To authenticate the session with a custom authenticator, simply pass the registered factory's name::
this.get('session').authenticate('authenticator:custom', {});
or when using one of the controller mixins:
App.LoginController = Ember.Controller.extend(Ember.SimpleAuth.LoginControllerMixin, {
authenticatorFactory: 'authenticator:custom'
});
Also see the
API docs for Session#authenticate
,
LoginControllerMixin
and
AuthenticationControllerMixin.
If the Ember.js application makes requests to a backend server that requires
authorization and an authorizer is specified for Ember.SimpleAuth's setup (see
API docs for Ember.SimpleAuth.setup
),
Ember.SimpleAuth sets up an
$.ajaxPrefilter
that is used
to authorize AJAX requests.
Ember.Application.initializer({
name: 'authentication',
initialize: function(container, application) {
Ember.SimpleAuth.setup(container, application, {
authorizerFactory: 'authorizer:custom'
});
}
});
While the authenticator acquires some sort of secret information from an authentication provider when it authenticates the session, the authorizer uses that secret information to authorize subsequent requests. There is always only one authorizer in an application.
As the authorizer depends on the information provided by the authenticator, the two have to fit together.
Ember.SimpleAuth does not include any authorizers in the base library but offers extension libraries that can be loaded in the application as needed:
- ember-simple-auth-oauth2 provides an OAuth 2.0 authorizer
- ember-simple-auth-devise provides an authorizer compatible with the popular Ruby on Rails authentication plugin devise
Besides the option to use one of the predefined authorizers from the extension
libraries, it is easy to implement custom authorizers as well. All that is
necessary is to extend Authorizers.Base
and implement one method (see the
API docs for Authorizers.Base
).
To use a custom authorizer, register it with Ember's container and configure it in the initializer:
var CustomAuthenticator = Ember.SimpleAuth.Authenticators.Base.extend({
...
});
Ember.Application.initializer({
name: 'authentication',
initialize: function(container, application) {
container.register('authorizer:custom', CustomAuthenticator);
Ember.SimpleAuth.setup(container, application, {
authorizerFactory: 'authorizer:custom'
});
}
});
Ember.SimpleAuth will never authorize cross origin requests so that no secret information gets exposed to 3rd parties. To enable authorization for additional origins (for example if the REST API of the application runs on a different domain than the one the Ember.js application is served from), additional origins can be whitelisted when Ember.SimpleAuth is set up (beware that origins consist of protocol, host and port where port can be left out when it is 80 for HTTP or 443 for HTTPS):
Ember.Application.initializer({
name: 'authentication',
initialize: function(container, application) {
Ember.SimpleAuth.setup(container, application, {
crossOriginWhitelist: ['http://some.other.domain:1234']
});
}
});
Ember.SimpleAuth persists the session state so it survives a page reload.
There is only one store per application that can be configured during setup
(see the
API docs for Ember.SimpleAuth.setup
):
Ember.Application.initializer({
name: 'authentication',
initialize: function(container, application) {
Ember.SimpleAuth.setup(container, application, {
storeFactory: 'session-store:local-storage'
});
}
});
Ember.SimpleAuth comes with 2 bundled stores:
The localStorage
store (see the
API docs for Stores.LocalStorage
)
stores its data in the browser's localStorage
; this is the default store.
The ephemeral store (see the
API docs for Stores.Ephemeral
)
stores its data in memory and thus is not actually persistent. This store
is mainly useful for testing. Also the ephemeral store cannot keep multiple
tabs or windows in sync of course as these tabs/windows cannot share memory.
A cookie based store is available in the extension library ember-simple-auth-cookie-store which is not recommended to be used though as it has some drawbacks.
Implementing a custom store is as easy as implementing custom authenticators or
authorizers. All that is necessary is to extend Stores.Base
and implement
three methods (see the
API docs for Stores.Base
).
To run the examples you need to have node.js and grunt installed. If you have those, simply run:
git clone https://github.com/simplabs/ember-simple-auth.git
cd ember-simple-auth
npm install
grunt server
Open http://localhost:8000/examples to access the examples.
- Ember App Kit: https://github.com/erkarl/ember-app-kit-simple-auth
- Ember.SimpleAuth with Rails 4: https://github.com/ugisozols/ember-simple-auth-rails-demo
To install Ember.SimpleAuth and/or its extension libraries in an Ember.js application you have several options:
- If you're using Bower, just add it to your
bower.json
file:
{
"dependencies": {
"ember-simple-auth": "https://github.com/simplabs/ember-simple-auth-component.git"
}
}
- Download a prebuilt version from the releases page
- Build it yourself
- If you're using Ruby on Rails, you can add the (unofficial) source gem that
supports the Ruby on Rails asset pipeline by adding it to your
Gemfile
:
gem 'ember_simple_auth-rails'
To build Ember.SimpleAuth yourself you need to have node.js and grunt installed. If you have those, simply run:
git clone https://github.com/simplabs/ember-simple-auth.git
cd ember-simple-auth
npm install
grunt dist
After running that you will find the compiled source files (including minified
versions) in the dist
directory.
If you want to run the tests as well you also need PhantomJS. You can run the tests with:
grunt test
You can also start a development server by running
grunt server
and then run the tests in the browser at http://localhost:8000.