48

Does anyone have experience creating an authentication mechanism with the new router in pre4?

Here are some of my thoughts so far:

  • In order to completely separate the view (Ember app) from the server (Rails app) I want to use token authentication. I will likely use Devise on the Rails server.
  • I need something like a before_filter equivalent in the Ember app where I can check if there is a current user and if that user has an authentication token set.
  • The Rails server will return the current auth token on every call. If it returns a null auth token the Ember app should detect this and transition to the unauthenticated state, redirecting to the login view.

I suspect I should be using an Ember state machine for this but I'm not sure how to proceed. Anyone tackled this problem yet?

5 Answers 5

51

UPDATE: Like @DustMason says in his answer, check out the awesome embercasts for authentication best-practices.

In order to completely separate the view (Ember app) from the server (Rails app) I want to use token authentication. I will likely use Devise on the Rails server.

Makes sense.

I need something like a before_filter equivalent in the Ember app where I can check if there is a current user and if that user has an authentication token set.

You can add an enter hook on routes, this is roughly equivalent to a before_filter. But not sure that's the best place to check for an auth-token.

The Rails server will return the current auth token on every call.

Makes sense. We use cookie-auth and fetch current user profile by calling /api/me but either should work.

If it returns a null auth token the Ember app should detect this and transition to the unauthenticated state, redirecting to the login view.

Thing about this approach is that (unlike rails) it's not easy to "protect" access to a particular ember routes. And no matter what a user can always pop open JS console and enter whatever state they want. So instead of thinking "user can only get into this state if authenticated" consider "what if unauthenticated user somehow navigates to this route"

I suspect I should be using an Ember state machine for this but I'm not sure how to proceed. Anyone tackled this problem yet?

Our auth needs are pretty simple so we've not found the need for a state machine. Instead we have an isAuthenticated property on ApplicationController. We use this property in application.hbs to replace the main view with a login form when a user is not authenticated.

{{if isAuthenticated}}
  {{render "topnav"}}
  {{outlet}}
{{else}}
  {{render "login"}}
{{/if}}

From ApplicationRoute, we fetch user profile:

App.ApplicationRoute = Ember.Route.extend({
  model: function() {
    var profiles;
    profiles = App.Profile.find({ alias: 'me' });
    profiles.on("didLoad", function() {
      return profiles.resolve(profiles.get("firstObject"));
    });
    return profiles;
  }
});

Then our ApplicationController computes it's isAuthenticated property based on the profile that was returned.

Sign up to request clarification or add additional context in comments.

9 Comments

I marked accepted as this got me on the right track. Can you elaborate on the comment you made: "Makes sense. We use cookie-auth and fetch current user profile by calling /api/me but either should work." What is cookie-auth? Do you still use token authentication and store the token in a cookie after logging in?
Sure - guess "cookie-auth" isn't really a thing. What I mean is that we are using rails cookie-store for sessions. Our API expects the user to have a valid session, and returns current_user when /api/me is requested.
Quick note, but the "enter" hook you mention is now deprecated and instead replaced with "activate" (and corresponding "deactivate")
What if the ember app thinks it's authenticated but it's not (e.g. server has expired the session key)? How does it detect this state and redirect back to the login form?
@adamsmith that's a good question. Not an issue for us, but i can see how it might be. Ideally your API will return an HTTP 403 the next time an API call is made. Then customize your ember-data adapter to handle this case and modify isAuthenticated property of your application controller.
|
19

I would suggest using ember-auth for that. It implements all the needed functionality and works very well in my opinion.

Also there is a demo and tutorial with Devise on Rails by the same author.

I also have implemented a basic Ember application based on Ember-auth with Devise token authentication and example Oauth for Google and LinkedIn that can be found here and is live here: https://starter-app.herokuapp.com

Comments

12

I recently changed from a bespoke auth system to using ember-simple-auth and found it very easy to integrate with my app. It fulfills all of the OPs requirements and also has built in support for refresh tokens.

They have a really nice API and a great set of examples. Anyone interested in token based auth should check it out.

Comments

4

The newly released Ember async router makes setting up a nice auth flow easier in my opinion! Check out the two-part series on http://www.embercasts.com/ for a good example

Comments

3

Josep's example app is really nice. I made a copy of his repo to show how to do it with ActiveRecord instead of mongoid, and also enable the Devise confirmable module. You can find it here. This repo was reconstructed from scratch, rather than forked, as I wanted to force myself to go through all of the steps to get it working. I'll update this answer if I add a fork with the necessary changes to get it to work.

2 Comments

Great, thanks Josep. I will work on getting that done sometime this week.
Many thanks for your very useful contribution to ActiveRecord support.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.