As part of the work done for #3025905-10: Login URLs not working on Drupal 8 subdirectory sites, cookie domains are currently set to drop any subdomains because they're assumed to be the internal names of subdirectory sites.
For example, example.com/site1 is represented internally as site1.example.com. So when we set the cookie domains, we want it to be example.com as that's how the site will be accessed.
However, if we're talking about foo.example.com/site1, the cookie domain should be foo.example.com, not simply example.com, which is the way it works now. In fact, it's the parent site whose cookie domain is incorrect. Any child subdirectory sites (e.g. foo.example.com/site1) will set this correctly as foo.example.com while the parent sets it as example.com. (It's fine for them to be on the same domain because the path is different: / for the parent and /site1 for the child.)
Here is the offending code:
/**
* Extract our cookie domain from the URI.
*/
protected function getCookieDomain() {
$uri = explode('.', $this->uri);
# Leave base domain; only strip out subdomains.
if (count($uri) > 2) {
$uri[0] = '';
}
return implode('.', $uri);
}
Note that any subdomains are stripped, whether or not we're dealing with a subdirectory site.
What should be happening instead is that subdomains should only be stripped if they're part of the internal name of a subdirectory site. So if we're dealing with a subdirectory site, then strip its domain. Otherwise, don't do anything. We need to make the net smaller.
| Comment | File | Size | Author |
|---|---|---|---|
| #8 | 3066538-8-provision-cookie_domain_redirection.patch | 729 bytes | helmo |
| #3 | 3066538.is_hosting_subdir.patch | 650 bytes | spiderman |
Comments
Comment #2
colanBetter title.
Comment #3
spidermanI've rolled this simple patch which appears to fix the problem with the cookie subdomains, although it has a couple other issues:
1. it calls the internal _hosting_subdirs_is_a_subdir_site() function, which by convention should only be called within the hosting_subdirs module (perhaps the logic there should be exposed, or reproduced here?)
2. it appears to break my ability to login to a subdir site when using Nginx.
I'm digging into this further, but thought I'd share the patch in case anyone has comments. I'm suspicious because I noticed that logging into a subdir site using Apache doesn't work for me, regardless- and according to the earlier tickets @colan mentioned, I believe both webservers should allow me to run a password reset and login.
Comment #4
spidermanWith thanks to @ergonlogic for the lead, I've gone back to the original commit that introduced the bug, creating and writing the
aegir.services.ymlto specify the cookie domain.As an experiment, I've commented out the entire
aegir.services.tpl.phpso no cookie domain is explicitly set by that mechanism. Having cleared caches, I find I can "goto" my test parent site or my test subdirectory site, get logged into each independently (ie. logging into one doesn't log me into the other, and vice versa). Inspecting the cookies on each page, I see I have 2 cookies, each with domain as the full parent uri (eg. .foo.aegir.local), and a path of '/'.I'm not entirely clear how this is working, off-hand, and I might be missing the problem or the reason the
aegir.services.ymlwas introduced, but I *think* this is the behaviour we want. I'm not certain of the actual failure @colan was describing originally on this ticket, but having reverted to not explicitly setting cookie domain, Drupal seems to handle things elegantly. Perhaps some of the other commits on https://www.drupal.org/project/provision/issues/3025905 took care of the original problem there?Comment #5
ergonlogicI suspect so. We should probably just revert b441a70eb. If we do, it'll leave behind unused
aegir.services.ymlfiles. They shouldn't break anything, as they will no longer be included insettings.php. Unfortunately, I don't know of anyhook_update_N()mechanism in Drush that'd allow us to delete these cleanly as a one-off.Comment #6
colanMaybe also check siblings as well, that you don't get automatically logged into or out of
/site1if doing so on/site2?Comment #7
acThis also cause cookie issues with any sites in Aegir that don't start with www.
The cookie domain in aegir.services.yml ended up as simply .com
This is a major issue that needs to be fixed ASAP.
Comment #8
helmo commentedAnother angle on this ...
When you have a site with alias domains, and set a redirect to something other then the name with which the site was created then you can nolonger login.
The cookie domain set in the services.yml is only based on this->uri (the site node title)
This prevents logins even with a login link.
@ac: The getCookieDomain() function had a line
if (count($uri) > 2) {which should prevent 'example.com' turning into '.com' ... but example.co.uk might be a different story. ( we should look at core https://git.drupalcode.org/project/drupal/blob/7.x/includes/bootstrap.in... )It seems that this cookie domain is needed just for the subdir sites ... could we restrict it to just those sites? ... the settings.php templates are testing for
isset($_SERVER['RAW_HOST']Comment #9
philosurfer commentedIn regards to reverting on #5.
An update hook could try and remove the file but in most cases will fail because of file permissions set on that folder (?), if it fails it should be added as a warning in reports that the file can be removed until such date we need to use it again. An addendum to the documentation on the project page should be sufficient for helping people stumbling upon this issue later on.
Comment #10
llamechWe have tested the following on nginx with the latest version (7.x-3.180) using a Drupal 7 site, and here's what we see:
Comment #11
ac@helmo yes you are correct - the domains we had issues with were all .com.au
@llamech did you check any second level domains like .com.au?
Comment #12
llamechToday, we have tested the following on nginx with the latest version (7.x-3.180) using a Drupal 8 site, and here's what we see:
Comment #13
llamechNow, as per @ac, we've tried the same use cases as above using a 2-part TLD (example.com.au) with Drupal 8 on nginx.
After observing the failure to login in the first example, we only tested the case where we remove aegir.services.yml (since this approach worked on any previous issues that had come up); it fixed whatever issue was blocking login in the first case above, and we saw no further issues with the other cases.
It seems that reverting the commit that introduced aegir.services.yml (mentioned by @ergonlogic above) would be a good first step.
Comment #15
ergonlogicWe reverted the problematic commit, so we'll no longer generate `aegir.services.yml`, nor include it in `settings.php`.
As I mentioned in #5, this won't remove existing `aegir.services.yml` files, but they won't be used either. I think a small post-verify hook to clean up these files should be fine. If we ever decide to re-implement the Aegir-generated services file, we can drop the cleanup code.
Comment #17
ergonlogicCleanup code added in 221354d8.
This should be fixed now in 7.x-3.x, and will make it into the next release.
Comment #19
jon pughNoting here that this issue has arisen again: https://www.drupal.org/project/provision/issues/3102849
It would be great if the manual test scripts posted above could be added to the automated tests suites: https://github.com/aegir-project/tests
https://www.drupal.org/project/provision/issues/3066538#comment-13266027
Comment #20
colan