Auth UI

heartsentwined edited this page Oct 18, 2013 · 7 revisions

Auth UI


CHANGES This page has been updated for the 9.x branch. Legacy instructions are gone - clone this wiki repo and checkout the 8.x tag.


Adapters

ember-auth allows customizing for implementation-specific behavior by using different adapters and extending from different modules. We will use

  • the jquery request adapter - use jQuery.ajax() to send server requests
  • the json response adapter - responses will be formatted in json
  • the token strategy adapter - use token authentication
  • the cookie session adapter - persistent storage (if any) in cookies
  • the emberData module - integration for ember-data as persistence library

We have already installed these as gems. Include them into our assets.

application.coffee:

# ...
#= require ember-auth
#= require ember-auth-request-jquery
#= require ember-auth-response-json
#= require ember-auth-strategy-token
#= require ember-auth-session-cookie
#= require ember-auth-module-ember-data
# ...

Extend our app's auth object from Em.Auth:

auth.coffee

EmberAuthRailsDemo.Auth = Em.Auth.extend
  request: 'jquery'
  response: 'json'
  strategy: 'token'
  session: 'cookie'

  modules: ['emberData']

Include it into the sprockets stack:

ember-auth-rails-demo.coffee:

#= require ./auth
#= require ./store
#= require_tree ./models
#= require_tree ./controllers
#= require_tree ./views
#= require_tree ./helpers
#= require_tree ./templates
#= require_tree ./routes
#= require ./router
#= require_self

Config

Remember our server's token authentication API? It exposes two end points:

  • POST /api/sign_in
    • params: email and password
    • returns: auth_token and user_id
  • DELETE /api/sign_out
    • param: auth_token

We also expect to pass the auth_token in as a key-value pair in the query params / post data. This is the default, but we'll declare it explicitly nonetheless.

We will pass this to ember-auth. auth.coffee:

EmberAuthRailsDemo.Auth = Em.Auth.extend
  # ...
  signInEndPoint: '/api/sign_in'
  signOutEndPoint: '/api/sign_out'
  tokenKey: 'auth_token'
  tokenIdKey: 'user_id'
  tokenLocation: 'param'

Auth widget

We will make an ever-present widget for our auth UI. In a production app you can have it at the end of your navbar, probably with links to the "account" page, etc. It is also the simplest to make.

Start with a template, for the auth widge area. If you have worked with devise views, you will be familiar with branching with the condition current_user.

if current_user
  # signed in
else
  # signed out
end

The ember-auth equivalent is auth.signedIn.

We plan to display an auth/sign-out template if the user is already signed in, and auth/sign-in if not.

templates/auth.emblem:

if auth.signedIn
  render 'auth/sign-out'
else
  render 'auth/sign-in'

Sign in

The auth/sign-in template will be paired with its controller, which will provide the email and password properties, and will implement a signIn action to handle the actual sign in.

controllers/auth/sign-in.coffee:

EmberAuthRailsDemo.AuthSignInController = Em.Controller.extend
  email: null
  password: null

  actions:
    signIn: ->
      @auth.signIn
        data:
          email:    @get 'email'
          password: @get 'password'

On to the template first, so that we have a full picture. It is a simple form, with input fields binding to the controller's email and password properties. We will use the default input helper for simplicity.

templates/auth/sign-in.emblem:

form submit='signIn'
  label Email
  =input type='text' value=email
  label Password
  =input type='password' value=password
  button Sign In

All usual ember stuff. We have utilized the auth.signIn() helper in the submit action. It accepts an object of params under the data key, to be passed to the sign in API end point. In our case, our server expects email and password, so we pass them in.

ember-auth will then send a POST request to our specified API end point, and set auth.authToken and auth.userId (among others) when it has successfully retrieved the authentication token.

Sign out

The auth/user template is similar - and simpler. We just need to implement a signOut action, which calls the auth.signOut() helper.

controllers/auth/sign-out.coffee:

EmberAuthRailsDemo.AuthSignOutController = Em.Controller.extend
  actions:
    signOut: ->
      @auth.signOut()

templates/auth/sign-out.emblem:

form submit='signOut'
  button Sign out

The auth.signOut() helper also accepts an object of params, again under the data key, to be passed to the sign out API end point. However, since we have already signed in, the authentication token would also be passed in this API call. So, in our case, we don't need to do anything extra.

The helper will set auth.authToken and auth.userId (among others) to null when it receives a successful response.

Insert the UI

We want our widget to be ever-present in our app, so let's add it to our application template.

templates/application.emblem:

render 'auth'
outlet

Checkpoint

Fire up the server.

$ foreman start

You should see the new sign in form (because you have not signed in yet). Feel free to try signing in and out, with our seed users:

  • email: foo@example.com, password: foopassword
  • email: bar@example.com, password: barpassword

You can also open your console, inspect the async requests, and see what ember-auth is doing behind the scenes.

Continue to Model UI.