views:

737

answers:

3

Is it possible to set the cookie domain to something other than the current domain when a session is created with Authlogic?

When a new account is created from our signup domain, I'd like to redirect the user to their subdomain account and log the user in.

Current controller:

def create
  @account = Account.new(params[:account])
  if @account.save
    @user_session = @account.user_sessions.create(@account.users.first)
    # I'd like the cookie domain to be [@account.subdomain, APP_CONFIG[:domain]].join(".")
    redirect_to admin_root_url(:host => [@account.subdomain, APP_CONFIG[:domain]].join("."))
  else
    render 'new'
  end
end
A: 

If you want to log them in on the subdomain, you can use Authlogic's single use token.

Check out the Params module for an example on logging in with the single use token.

Naturally, your action will log them in and create their session (on the subdomain) so they don't have to re-authenticate for the next request.

There are options to set the domain for the cookie in process_cgi() and session(), but I don't see a way to set those per-request in Authlogic. The authlogic mailing list is pretty responsive, though, and this seems like a pretty standard use-case that someone there would have tried and figured out. And uh, I saw your note on the google group, so never mind that.

wesgarrison
The single_access_token is not designed for persistant sessions -- it's designed for single requests (getting a feed that requires authentication, API access, etc). Subsequent requests that do not contain the key will not have a session.
bensie
Yep. In that action, you would create their new-to-that-subdomain session.
wesgarrison
+2  A: 

If you do:

config.action_controller.session[:domain] = '.YOURDOMAIN.COM'

in your production.rb file, that will allow you to have everyone logged in on all subdomains of your subdomain. If you then add a filter (or whatever, but I use a filter so I know that works) that checks that someone is actually using the right domain before you show controller stuff, it works pretty well.

As an example, you could store the appropriate subdomain for the session as a session variable and give people link options to their specific things if they were on your main domain or looking at a page on someone else's subdomain.

This seems to be the general pattern for doing this sort of thing -- if you set a cookie specific to the subdomain otherwise you won't be able to tell when they've logged in to the main site. I also have a 'users_domain?' helper that ends up getting called occasionally in views when I do this.

If you don't want to have those sorts of common web design patterns, wesgarrion's single use -> session creation on subdomain is also a way to go. I just thought I'd mention this as a design / interaction / code issue.

corprew
A: 

If you have an application with multiple subdomains and don't want session cookies to be shared among them, or worse - have a top-level .domain session cookie with the same session_key floating around alongside your subdomain session cookie (Rails will keep one and toss the other - I believe simply based on the order in the request header) - you can use the dispatcher hooks to force the session cookie to subdomains.

Include the hook in ActionController from an extension.

base.send :after_dispatch, :force_session_cookies_to_subdomains

Set the domain this in your after_ dispatch hook.

@env['rack.session.options'] = @env['rack.session.options'].merge(:domain => 'my_sub_domain' end)

For us, we look at the @env[HTTP_HOST] to determine what [my_sub_domain] should be.

With this approach, the user's login must occur at the subdomain for the browser to accept the subdomain'ed cookie (unless using a pattern like the Authlogic Params to propagate to the next request against the subdomain).

Note: The browser will reject the subdomain'ed cookie when the request comes from the higher level domain. For us, this isn't a bad thing - it results in the same outcome that we require, that a top level session cookie doesn't get created and later sent to subdomains.

Another approach to a similar end might be to force a cookie to not be set when not from a subdomain. Not spending much time on it, the way I was able to accomplish this was -

request.env["rack.session"] = ActionController::Session::AbstractStore::SessionHash.new(self, request.env)

in an after filter in ApplicationController.

dzello