#695 open
Henry Baragar

the "remember me" auth_token does not work when there is more than one hobo application running on a server

Reported by Henry Baragar | April 11th, 2010 @ 08:29 PM | in Hobo 1.3 (Rails 3)

I now have several hobo applications (each with its own uat and production environments) all running on a single server, which causes the "remember me" functionality to fail because the auth_token is shared amongst all the applications.

For example,

  1. I log into application_A on my server with the "remember me" tick box checked
  2. I log into application_B on my server with the "remember me" tick box checked

At this point, the auth_token cookie from application_B has overwritten the one from application_A.

I believe that the auth_token cookie name should be created from the session cookie name by replacing the "session" with "auth_token".

For example, if we had a session cookie name of:

  • applicationA_session

we should use an auth_token cookie name of:

  • application_Aauth_token

Here is a patch to do just that:

--- lib/hobo/authentication_support.rb.orig 2010-03-03 21:49:39.521489182 -0500
+++ lib/hobo/authentication_support.rb      2010-04-11 15:27:27.960313913 -0400
@@ -100,7 +100,7 @@

     def authenticated_user_from_cookie
       !logged_in? and
-          cookie = cookies[:auth_token] and
+          cookie = cookies[auth_token] and
           (token, model_name = cookie.split) and
           user_model = model_name._?.safe_constantize and
           user = user_model.find_by_remember_token(token) and
@@ -109,10 +109,15 @@
     end

     def create_auth_cookie
-      cookies[:auth_token] = { :value => "#{current_user.remember_token} #{current_user.class.name}",
+      cookies[auth_token] = { :value => "#{current_user.remember_token} #{current_user.class.name}",
                                :expires => current_user.remember_token_expires_at }
     end

+    def auth_token
+      session_cookie_key = "" + ActionController::Base.session_options[:key]        # Now unfrozen
+      session_cookie_key.sub!(/session/,"auth_token") || session_cookie_key + "_auth_token"
+    end
+
     private
     @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization)
     # gets BASIC auth info

Comments and changes to this ticket

  • Matt Jones

    Matt Jones April 11th, 2010 @ 10:27 PM

    Note that this is a design issue inherited from restful_authentication; it could also be regarded as a "feature" in some implementations (multiple apps on the same domain authenticating against a single user database).

    Not sure if this is related or not:
    http://nessence.net/2009/10/26/restful-authentication-subdomain-fu-...

    Note that the above link is specifically trying to get the opposite effect, persisting a single :auth_token across multiple subdomains.

  • Bryan Larsen

    Bryan Larsen April 12th, 2010 @ 09:14 PM

    Matt, are you comfortable with this patch? It doesn't seem unreasonable to me.

  • Matt Jones

    Matt Jones April 12th, 2010 @ 09:55 PM

    It seems fairly reasonable to me, but I'm still not convinced it's a correct solution to Henry's issue. If I'm reading his description correctly, what he's really looking for is the 'Path' attribute for cookies, to segment cookies from http://example.com/app_one/ vs. http://example.com/app_two/. I was shocked to discover there is not (AFAIK) any simple way to do this in Rails - I expected a config option of some sort to set the default :path value for cookies set via cookie[:foo] = bar.

    @Henry: I'm guessing that you're setting config.action_controller.relative_url_root for each app? Maybe we could add an option to add a :path option to the cookie? Or maybe this monkey-patch would help:

      class ActionController::CookieJar
        def []=(key, options)
          if options.is_a?(Hash)
            options.symbolize_keys!
          else
            options = { :value => options }
          end
    
          options[:path] = ActionController::Base.relative_url_root || "/" unless options.has_key?(:path)
          super(key.to_s, options[:value])
          @controller.response.set_cookie(key, options)
        end
    
        # Removes the cookie on the client machine by setting the value to an empty string
        # and setting its expiration date into the past. Like <tt>[]=</tt>, you can pass in
        # an options hash to delete cookies with extra data such as a <tt>:path</tt>.
        def delete(key, options = {})
          options.symbolize_keys!
          options[:path] = ActionController::Base.relative_url_root || "/" unless options.has_key?(:path)
          value = super(key.to_s)
          @controller.response.delete_cookie(key, options)
          value
        end
      end
    

    (drop in an initializer; this could be shorter, but alias_method_chaining a []= method is messy. Should work, but not tested.)

    In any case, the existing behavior can be useful - several apps mounted on the same host with a common user table would be a standard use case. Whatever resolution we come up with, it should be switchable.

  • Matt Jones

    Matt Jones September 14th, 2011 @ 10:22 PM

    • State changed from “new” to “open”
    • Milestone set to Hobo 1.3 (Rails 3)
    • Milestone order changed from “0” to “0”

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

Tags

Pages