The API docs for Ember Simple Auth Devise are available here
This is an extension to the Ember Simple Auth library that provides an authenticator and an authorizer that are compatible with customized installations of Devise.
As token authentication is not actually part of Devise anymore, there are some customizations necessary on the server side (most of this is adapted from José Valim's gist on token authentication).
First, a new column for the authentication token must be added to the users table:
class AddAuthenticationTokenToUser < ActiveRecord::Migration
def change
add_column :users, :authentication_token, :string
end
end
That authentication token must be auto-generated by the model on creation:
class User < ActiveRecord::Base
before_save :ensure_authentication_token
def ensure_authentication_token
if authentication_token.blank?
self.authentication_token = generate_authentication_token
end
end
private
def generate_authentication_token
loop do
token = Devise.friendly_token
break token unless User.where(authentication_token: token).first
end
end
end
By default, Devise's sessions controller only responds to HTML request. In order for it to work with Ember Simple Auth it must also respond to JSON. To achieve that, define a custom sessions controller (if HTML responses are not needed the format handling can be left out of course):
class SessionsController < Devise::SessionsController
def create
respond_to do |format|
format.html { super }
format.json do
self.resource = warden.authenticate!(auth_options)
sign_in(resource_name, resource)
data = {
user_token: self.resource.authentication_token,
user_email: self.resource.email
}
render json: data, status: 201
end
end
end
end
and configure Devise to use that controller instead of the default one:
MyRailsApp::Application.routes.draw do
devise_for :users, controllers: { sessions: 'sessions' }
end
Finally, the Rails application must authenticate users by their authentication token and email if present:
class ApplicationController < ActionController::Base
before_filter :authenticate_user_from_token!
private
def authenticate_user_from_token!
authenticate_with_http_token do |token, options|
user_email = options[:user_email].presence
user = user_email && User.find_by_email(user_email)
if user && Devise.secure_compare(user.authentication_token, token)
sign_in user, store: false
end
end
end
end
The Rails application should also not issue session cookies but authentication
should be done exclusively via the authentication token as described above. The
easiest way to disable sessions in Rails is to add an initializer
config/initializers/session_store.rb
and disable the session store in that:
Rails.application.config.session_store :disabled
If disabling sessions completely is not an option, make sure no session cookies are sent for JSON requests as described here.
If the server sends session cookies to the Ember frontend this will lead to the situation that the user is actually still logged in after Ember Simple Auth invalidates the session as the Rails session cookie will still be present because Ember Simple Auth does not know anything about that cookie and will not delete it on session invalidation!
In order to use the Devise authenticator (see the
API docs for Authenticators.Devise
)
the application needs to have a login route:
App.Router.map(function() {
this.route('login');
});
This route displays the login form with fields for identification
,
password
:
<form {{action 'authenticate' on='submit'}}>
<label for="identification">Login</label>
{{input id='identification' placeholder='Enter Login' value=identification}}
<label for="password">Password</label>
{{input id='password' placeholder='Enter Password' type='password' value=password}}
<button type="submit">Login</button>
</form>
The authenticate
action that is triggered by submitting the form is provided
by the LoginControllerMixin
that the respective controller in the application
can include (the controller can also implement its own action and use the
session API directly; see the
API docs for Session
).
It then also needs to specify the Devise authenticator to be used:
// app/controllers/login.js
import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin'
export default Ember.Controller.extend(LoginControllerMixin, {
authenticator: 'simple-auth-authenticator:devise'
});
The authorizer (see the
API docs for Authorizers.Devise
)
authorizes requests by adding user_token
and user_email
properties from the
session in the Authorization
header:
Authorization: Token token="<user_token>", user_email="<user_email>"
To use the authorizer, configure it in the global environment object:
window.ENV = window.ENV || {};
window.ENV['simple-auth'] = {
authorizer: 'simple-auth-authorizer:devise'
}
To install Ember Simple Auth Devise in an Ember.js application there are several options:
-
If you're using Ember CLI, just add the Ember CLI Addon to your project and Ember Simple Auth Devise will setup itself.
-
The Ember Simple Auth Devise extenion library is also included in the "ember-simple-auth" bower package both in a browserified version as well as an AMD build. If you're using the AMD build from bower be sure to require the autoloader:
require('simple-auth-devise/ember');
The browserified version will, like the Ember CLI addon, also setup itself once it is loaded in the application.
-
Download a prebuilt version from the releases page