Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember.js session cookie based authentication with Rails and devise

I'm looking to satisfy 3 goals with my Ember.js app authentication using rails, devise and a cookie based session.

  1. Redirected to #/sessions/new if they're not logged in.
  2. Always show the current user's information in the application template.
  3. If the user is logged in and they go to #/some/route directly. The current user should be loaded on load.

I've watched these embercast videos: Client-side Authentication Part 1 & Client-side Authentication Part 2. They're a little out of date but helpful.

But still can't full solution. Anyone have full Rails 4, Devise, Emberjs 1.0.0 example?

Biggest problem is having a strategy to load the current user on page load and setting the current user when the sign in form is submitted.

Right now this is my strategy:


App.User = Em.Object.extend();

App.User.reopenClass({
  current: function() {
    return Ember.$.getJSON("/users/current").then(function(data) {
      return data
    })
  }
});

App.ApplicationRoute = Ember.Route.extend({
  model: function() {
    return App.User.current();
  }
});

App.SessionsNewController = Ember.ObjectController.extend({

  actions: {
    save: function(data) {
      var self = this, data = this.getProperties('email', 'password');

      $.post("/sessions", { session: data }).always(function(response, status, data) {
        if (status == "success") {
          self.transitionToRoute('index');
        } else {
          self.set('errorMessage', data);
        }
      })

    },
  }

});

like image 911
jpoz Avatar asked Oct 16 '13 21:10

jpoz


1 Answers

I would not say this is not doable. But you will do lots of extra and unnecessary works to get the authentication working, which can all be done with a simple page redirect.

I've collected some opinions from Derick, the author of Backbone.Marionette. Though these are for Backbone but not Ember.js, the situation of client side authentication is same.

I find it painful and unnecessary to try and make Backbone/Marionette handle the authentication and re-loading of the authorized site stuff. Once they log in, redirect them to a different URL that the server handles, and have the server send down all the stuff that they need, as an authenticated user. https://stackoverflow.com/a/18151935

Another quote from Derick as well:

Right. And there’s a lot of cases where I just flat out say, “Do not do single-page applications,” as well. And a login screen is the biggest example of that. In all of the clients that I’ve had in the last couple of years, they’ve all asked me, “Hey, I’m having this problem. I’m trying to get my login screen to give me the current user information back from the server and redo all of this stuff on the screen without refreshing everything.” My answer every single time is, “Don’t do that." http://javascriptjabber.com/056-jsj-marionette-js-with-derick-bailey/

Also think about other cases, say Gmail. You won't get a smooth transition after click "Sign in" button on Gmail's sign in page. There will be redirect with rather big data loading as well :)

From users' perspective, they won't say Gmail is not great just because there is a redirect after signing in. After all signing/sign up is much much less frequent than daily mail operations.

So my suggestion is, reload all resources after user session changed. Let Rails and Devise do these dirty jobs in traditional fashion.

like image 68
Billy Chan Avatar answered Sep 20 '22 02:09

Billy Chan