Skip to content

Latest commit

 

History

History
 
 

ember-simple-auth-devise

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

The API docs for Ember Simple Auth Devise are available here

Ember Simple Auth Devise

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 your user's credentials as well as the token are exchanged between the Ember.js app and the Rails server you have to make sure that this connection uses HTTPS!

Server-side setup

These instructions assume you're using the default Devise configuration and models. If you're using a custom model or attribute names, you can configure Ember Simple Auth Devise to work with those).

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
  respond_to :html, :json

  def create
    super do |user|
      if request.format.json?
        data = {
          token: user.authentication_token,
          email: user.email
        }
        render json: data, status: 201 and return
      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!

  # Enter the normal Devise authentication path,
  # using the token authenticated user if available
  before_filter :authenticate_user!

  private

  def authenticate_user_from_token!
    authenticate_with_http_token do |token, options|
      user_email = options[: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!

The Authenticator

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 value=identification placeholder='Enter Login'}}
  <label for="password">Password</label>
  {{input value=password placeholder='Enter Password' type='password'}}
  <button type="submit">Login</button>
</form>

The authenticate action authenticates the session with the 'simple-auth-authenticator:devise' authenticator:

authenticate: function() {
  var data = this.getProperties('identification', 'password');
  return this.get('session').authenticate('simple-auth-authenticator:devise', data);
}

The Authorizer

The authorizer (see the API docs for Authorizers.Devise) authorizes requests by adding token and email properties from the session in the Authorization header:

Authorization: Token token="<token>", email="<email>"

To use the authorizer, configure it on the application's environment object:

//config/environment.js
ENV['simple-auth'] = {
  authorizer: 'simple-auth-authorizer:devise'
}

Installation

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 extension 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