1

I have a requirement that I can append ?auth_token=x to any URL in my app and it will restore the session as if you had a cookie or the details were stored in local storage.

I've tried every manner I can think of to implement this over the last few hours but I'm not getting anywhere. Is this possible? Where should I be looking to add such functionality?

5
  • Did u try emberjs.com/guides/routing/query-params Commented May 1, 2014 at 2:40
  • Yes, that seems to work fine once everything is initialized and transitions are underway/finished. In my case I need to handle the authentication earlier than that so I have my own query param handling which works fine. The problem is where in ember-simple-auth I can trigger the authentication before it tries to redirect to the login page. Commented May 1, 2014 at 8:15
  • If you use Ember.SimpleAuth you already have the session state stored in localStorage. I'm not sure I understand what you're trying to achieve here. If you have a valid session in localStorage the session will be restored automatically. When you want to pass the token to the server in the URL instead of the Authorization header you can implement a custom authorizer (see here: github.com/simplabs/…). Commented May 2, 2014 at 17:13
  • I have a use case where there is no session already stored but user's need to be able to click a link or be passed through auth automatically from an external service and have a session created for them. I managed to achieve this, I'll post my code up in an answer shortly Commented May 8, 2014 at 8:04
  • @marcoow I've posted up my code, if you have a moment to take a look perhaps there is a better entry point available in Ember.SimpleAuth than what I have used? Commented May 8, 2014 at 8:22

2 Answers 2

1

I'm answering my own question here as I managed to find a solution, although how correct it is I'm not sure!

application.js:

// Really simple query parameter access
(function($) {
  $.QueryString = (function(a) {
    if (a == "") return {};
    var b = {};
    for (var i = 0; i < a.length; ++i)
    {
      var p=a[i].split('=');
      if (p.length != 2) continue;
      b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
    }
    return b;
  })(window.location.search.substr(1).split('&'))
})(jQuery);

initializers/authentication.js.coffee:

LocalStorageWithURLAuth = Ember.SimpleAuth.Stores.LocalStorage.extend
  init: ->
    if $.QueryString['auth_token']
      auth_token = $.QueryString['auth_token']
      Ember.$.ajax(
        async: false
        url: '/users/sign_in'
        type: 'POST'
        data: { auth_token: auth_token }
        dataType: 'json'
      ).then (data) =>
        @persist
          auth_token: data.auth_token
          auth_email: data.auth_email
          user_id: data.user_id
          authenticatorFactory: 'authenticator:devise'
        @_super()
      , (error) =>
        @_super()
    else
      @_super()

Ember.Application.initializer
  name: 'authentication'
  initialize: (container, application) ->
    Ember.SimpleAuth.Session.reopen
      user: (->
        userId = @get 'user_id'
        if !Ember.isEmpty userId
          container.lookup('store:main').find 'user', userId
      ).property('user_id')

    container.register 'session-store:local-storage-url', LocalStorageWithURLAuth

    Ember.SimpleAuth.setup container, application,
      storeFactory: 'session-store:local-storage-url'
      authenticatorFactory: 'authenticator:devise'
      authorizerFactory: 'authorizer:devise'
Sign up to request clarification or add additional context in comments.

Comments

0

I'm not sure I understand what you're doing. It seems like you're restoring the session from an auth token in the query string? That's actually what the authenticator's restore method is for (see docs here: http://ember-simple-auth.simplabs.com/ember-simple-auth-devise-api-docs.html#Ember-SimpleAuth-Authenticators-Devise-restore). Also when the application starts isn't the query string empty?

3 Comments

The query string has a one-time auth_token param in it that is used to create a new session. I spent a lot of time trying to get the restore method to work as I thought that was the best place for it but I only have part of the properties needed to restore a session and running an additional ajax request in that method proved tricky. The query string is present when the application starts as it's used to authenticate a user directly from a link in an e-mail or as part of a redirect chain in an external service.
Now that I think about it I think the issue I had with the restore method was that it wasn't actually being called when I needed so any code I put in there was useless. The approach I ended up with pre-populates LocalStorage so that the restore function runs and can restore the session.
The restore method is called when the application launches and whenever anything changes in the store.

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.