In my rails app, when I log in at the www.site.com address, I am logged in just fine. Although without logging out, I go to the site, http://site.com I am logged out, but still logged in at the www.site.com address if I go back.
I can't find anything to set in my environment variables, any idea as to how to keep this session across all domains on my domain?
Set the session cookie properly; that is, for .site.com and site.com rather than just for www.site.com.
When you set a session cookie for "site.com", that will be different than "www.site.com." You need to specify the "cookie_domain" as ".site.com" which will set the cookie or all subdomains as well. In PHP, you could use ini_set or session_set_cookie_params to set session.cookie_domain. In Rails, you can either add a small script to the enviroment.rb - something like:
ActionController::Base.session_options[:session_domain] = '.site.com'
(in this case you might also do some switching based on the domain name in production/test/development env's) or try some other configuration options.
Here's more than you'd ever want to know on the subject.
You should redirect www.site.com to site.com (or the other way around). If you don't do that, google may think it's two different sites.
In rails 2.3 this has been changed to:
config.action_controller.session[:domain] = '.example.com'
or if the session variable hasn't been created yet
config.action_controller.session = {:domain => '.example.com'}
See Losing session in rails 2.3.2 app using subdomain
since they alias www. to .; couldn't you just prepend www. onto the .?
Related
We are designing an application that will use Rails and Wordpress to interact with each other. We would like to have a universal logout where you could logout from either application and it would delete cookies from the other app. They will share the same host and toplevel domain. Is there a way to do this?
Access to a cookie is dependent on the domain of the server attempting to read the request -- and potentially the domain specified in the cookie. So assuming the domains match (e.g. www.example.com and www.example.com on both blog and Rails app) either should have access to a cookie set by the other.
If this is not the case (e.g. blog.example.com, www.example.com), you'll need to make sure when the cookie is set in either place, it's set for the entire domain (e.g. .example.com). But this doesn't help: while Rails can delete WP's cookie, and vice-versa, the method for creating (and using) them needs to be mutually understood.
So there's a twist here, since this is a session cookie; in this case, the cookie (which either app should have access to) is setting a value that is used and interpreted on the server side, where sessions are managed. WordPress and Rails both different methods and look for different cookies.
A solution (idea) would be to have one or the other subsystem catch incoming requests (most likely WP, and probably through some .htaccess RewriteRule, assuming you're using Apache) and create an intermediate cookie that the other could check that provides sufficient proof that the user has logged in correctly. WP's PHP for this is pretty good, and easily extended -- you just need to create some token that's a shared secret between the two apps (one of the values in wp-config.php such as LOGGED_IN_KEY might be a good option).
Maybe a solution would be to take the publicly available value from the WP cookie for username, and append the shared secret value and (in both systems) create an MD5 hash to store in a cookie. In this case, Rails' authentication would subordinate to WP's, so you would need to make sure Rails knew to delegate things like forgotten password, changed password, etc, to WP's mechanisms.
Obviously I am thinking aloud, but maybe this is a path to consider.
In any case, this is preferable to having both systems know how to trust the other's authentication.
Fiddling with cookie deletion appears to be dirty and error prone.
You might rather want to have a look at auth providers and the according plugins such as:
OAuth (WP - Rails; maybe make either side an OAuth provider)
CAS (WP - Rails)
LDAP (WP - Rails)
...
Maybe it's an option to switch from WP to one of Rail's CMS like:
Refinery CMS
Typo
...
I'm running into an issue with getting the right cookies for the current subdomain. I have two different instances of the same application, one running at the www subdomain and the other running at the test subdomain, but it seems like the test app is pulling in cookies from the www instead, even if there are explicit cookies for .test.domain.com (because it's different instances the same application, the cookie name is the same, but I am not looking to share sessions or cookies between the two instances).
Is there any way to specify what domain Rails should be looking for its cookies for? I have config.cookies.domain and config.action_controller.session[:domain] both set to "test.domain.com" (on the test app), but it doesn't seem to make any difference (and, as well, the cookies being set by the test domain are for some reason ending up with the domain .test.domain.com instead of test.domain.com and I'm not sure why, or if it's relevant).
Update: To make this more complex, I realized I do actually need the dot-prefaced cookie domains (ie. .test.domain.com and .domain.com), because in general, subdomains are supposed to share the main domain's cookies and session (it's only that the test subdomain is actually it's own application rather than being a subdomain of the main application). Obviously .domain.com cookies will apply to test.domain.com, but is there any way to make the explicitly test.domain.com ones take priority?
I'm planning the development of a website which will use parked domains to allow a single code base to drive multiple locale versions of a website.
What I have in mind is, when my index page is loaded to query my database to see if that particular host name has been added to a white list via a bespoke administration system. If so, the resultant row of site information (name, domain, locale etc.) is stored in a session variable.
My question is: if I did store this row in the session, would that session then be available to all of the other "sites" too (which I don't want)?
My thoughts for storing this information in the session were so I didn't have to query my database on each page for the site details. But if sessions are accessible by all parked domains, I'll have to re-factor my authentication handler too as that uses sessions (unrelated, I know!).
Thanks in advance.
Sessions usually rely on cookies, the browser will only send a cookie if the domain it was set from matches the domain of the resources you are requesting. So even if you're using the same code for all your various domains as long as that code is being referenced by different URLs you will be fine.
There´s a way to make session acessible to all parked domains and sub-domains.
I´m looking for an answer, and I didn´t found... But I wrote some code thats resolved this issue:
session_set_cookie_params(0,"/",$_SERVER["SERVER_NAME"]);
$_SESSION['session.cookie_domain'] = $_SERVER["SERVER_NAME"];
Good Luck for all future finders!
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
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.
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.
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.
I have a Rails app that sets a cookie and does a redirect to another server once the user is logged in. However, the cookie that the Rails app sets isn't seen by the server for some reason. I've tried setting http_only to false but I still can't even see the cookie unless the domain is the same as my Rails app. Here's the code I'm using to set the cookie:
cookies[:dev_appserver_login] =
{ :value => "#{email}:#{nick}:#{admin}:#{hsh}",
:domain => "webserver-to-redirect-to",
:expires => 30.days.from_now }
redirect_to session[:dest_url]
If I manually create a cookie with the Web Developer extension in Firefox it works fine, but not when Rails does it. Any ideas?
What are the redirecting and redirected-to servers? You can only set ‘domain’ to the current hostname or a parent domain, so if you're on a.example.com and you're redirecting to b.example.com, you have to set ‘domain’ to .example.com, not b.example.com as implied in the code snippet.
(And open domains like the .com TLD aren't themselves allowed as domain values, so if you want to pass a cookie from a.example.com to b.somewhereelse.com you will need a more complicated solution probably involving changing the code on somewhereelse.com.)
I still can't even see the cookie unless the domain is the same as my Rails app.
That's how cookies are supposed to work. If you're accessing it directly by IP, then as far as the web browser is concerned, your 'domain' is just your IP, so the same rules apply.
You can get around this in development mode by editing your /etc/hosts file and creating host names for your apps
127.0.0.1 app1.localdev.com, app2.localdev.com
Then, when the cookie is created set the domain to '.localdev.com' (note the preceeding period') which will allow any app at any subdomain of localdev.com to read it.
Another broader solution (which is better for production deploys, but more work to set up) is to set up a path proxy for the sub-app so requests to appdomain.com go to app1 and requests to appdomain.com/other-app/ are proxied to the other app. This lets them share the root domain and easily share cookies.