I have a multi-tenancy app with different accounts via subdomains. My login system uses cookies. I have a current_user helper in my application controller:
def current_user
@current_user ||= User.unscoped.find_by_auth_token(cookies[:auth_token]) if cookies[:auth_token]
end
helper_method :current_user
I log them in using this code:
cookies[:auth_token] = {value: user.auth_token, domain: :all}
This works well. What I'd like to do is show the user if they are signed into other accounts on the login page of a different account. In other words:
- Sign in to account1.derp.com
- Visit account2.derp.com/login
- Link on the bottom says (You're already signed into account1).
However, I can't seem to access cookies from the other account (this seems to be the intended behavior of the web/browser). So on that page, if I try to access cookies[:auth_token], its nil, because the cookie was for another account/url.
In addition I'd like to redirect the user to the same URL with their subdomain if they are signed in and they remove their subdomain from the URL...which requires the same thing - for me to be able to access the cookies for their account if the subdomain isn't there or its different.
Slack, for example, does both of these things. Try removing your subdomain from a page when logged in - you are automatically redirected back to the same page, with your subdomain (it basically just puts it back for you). Or if you go to the login page for another account, it tells you, "You're already signed in on another account."
I am trying to accomplish this, but as soon as I remove the subdomain, or go to a different one, the cookies[:auth_token] that I set when I logged in is nil. I am looking for some way to keep track of where the user is signed in, so in the case of a subdomain removal or visiting another subdomain, I know that they are already logged in to an account.
Does anyone have any experience with this type of cookie management or any insight on how I could keep track if the user is logged into a different account?
Ryan Bigg, author of "Multitenancy with Rails," responded to this via twitter.
That worked...I can read all the users cookies across domains that way:
I wasn't thinking this way because that would allow the user to login to any account (the way my code was working).
So I had a logged_in? helper, which was:
I ended up making another helper:
Then my require_login before_action:
Now logged_in? really just means that they are logged in somewhere, perhaps a different account, which I can use in the case I described above...and I can use the logged_in_to_current_account? helper for the before_action checks.
Then to finally answer my question, once the cookies can be shared across subdomains (and a lack of a subdomain), this code will redirect to the same page and add the user's subdomain back if it is removed:
I hooked that into a before_action and I'm good to go!