Skip to content

Wrong cookies set for store views with multidomain #8509

Closed

Description

@Noewt

Preconditions

Magento 2.1.4 CE
PHP Version 7.0.14-2a
Porto Theme 2.4.5
NGinx 1.9.11

Steps to reproduce

  1. Set up multiple store views within 1 website, like for example:
    storeview - code - base url
    GB - English - en_gb - www.store.com (default)
    GB - German - de_gb - www.store.com
    DE - German - de_de - www.store.de
    DE - English - en_de - www.store.de
  2. Go to default store, and use store switcher to change the storeview, for example the 'de_de' storeview.
  3. Switch back to the default storeview (en_gb)

Expected result

  1. A cookie named "store" should get created for www.store.de with "de_de" as content.
  2. A cookie named "store" should get created for www.store.com with "en_gb" as content.

Actual result

  1. A cookie named "store" is created with "en_gb" on domain www.store.de
  2. A cookie named "store" is created with "de_de" on domain www.store.com
    Both cookie-values don't match their domain.

If you now visit www.store.de, the store cookie gets called and it tries to load the en_gb storeview. This storeview has www.store.com set as base url, so it redirects to there. There's a store cookie set on that domain also, which tries to load the de_de storeview. You'll end up with a loop resulting in ERR_TOO_MANY_REDIRECTS.

Activity

  1. Flamestyle commented on Feb 11, 2017

    @Flamestyle

    Hello, @Noewt! I have same problem. Please write your steps for host nginx config. And setting in admin panel. You have found a solution?

  2. ajithkranatunga commented on Feb 14, 2017

    @ajithkranatunga

    Hello,

    Did you try to set correct Cookie Domain for each stores at Stores->Configuration->General->Web->Default Cookie Settings. Set store.de for de_de storeview and so on

  3. Noewt commented on Feb 14, 2017

    @Noewt
    Author

    I'm using this in the nginx config:

    map $http_host $MAGE_RUN_CODE {
      hostnames;
      .store.com en_gb;
      .store.de de_de;
    }
    

    So when there is no cookie set, it loads the default language set in the config. If there is a cookie set, it should 'override' the nginx config and redirect to the storeview set in the cookie.

    These are the admin settings for each storeview:

    storeview   base_url                cookie_domain
    en_gb       http://www.store.com    .store.com
    de_gb       http://www.store.com    .store.com
    de_de       http://www.store.de     .store.de
    en_de       http://www.store.de     .store.de
    
  4. Noewt commented on Feb 14, 2017

    @Noewt
    Author

    The same problem seems to be happening in this thread #3676
    The given solution (#3676 (comment)) doesn't work in this case, because I don't use additional store-codes after the base_url. It forces the nginx config over the cookie set.

  5. Flamestyle commented on Feb 21, 2017

    @Flamestyle

    Any decision on this issue?

  6. DavidLambauer commented on Mar 1, 2017

    @DavidLambauer
    Contributor

    I think I have the same Issue. The Problem I face with has the following behavior:

    http://recordit.co/hd5atWxFhu

    There is a condition in \Magento\Store\Controller\Store\SwitchAction which seems to be the source of the problem for me.

    The following Code contains a condition which checks if the current store is equal to the default. If so, the cookie of the store will be deleted. The problem is, that the cookie of the default store is getting deleted and the referer-store stil contains the cookie. That seems to be wrong in my opinion.

    May someone can check it as well.

    $defaultStoreView = $this->storeManager->getDefaultStoreView();
            if ($defaultStoreView->getId() == $store->getId()) {
                $this->storeCookieManager->deleteStoreCookie($store);
            } else {
                $this->httpContext->setValue(Store::ENTITY, $store->getCode(), $defaultStoreView->getCode());
                $this->storeCookieManager->setStoreCookie($store);
            }
    
  7. vherasymenko commented on Mar 30, 2017

    @vherasymenko

    Hi @Noewt , i try to reproduce your bug. after configuring web views, I see on cookies and they is correct.
    [https://youtu.be/uyd-nK0F9VI](See video) Maybe i forgot some settings for reproducing this bug. ?

  8. Flamestyle commented on Mar 30, 2017

    @Flamestyle

    Hi, @k7triton!
    You use only one domain.

  9. dakzilla commented on Mar 31, 2017

    @dakzilla

    Can confirm that the cookie is created in \Magento\Store\Controller\Store\SwitchAction for the wrong domain. The store cookie contains the store code from website A, but the domain the cookie is created for is website B. Magento starts acting very strangely because it thinks it's still on website A:

    • In the browser, the address bar show that the URL is website B
    • The theme and assets are loaded from website A

    On HTTPS, asset loading fails because of CORS policy. The expected behavior when switching store views is that the store cookie will be created on the correct domain.

  10. IlnitskiyArtem commented on Jul 10, 2017

    @IlnitskiyArtem

    Hi, @Noewt.
    Internal ticket MAGETWO-64885, which tracks this GitHub issue, is in our issue backlog.

  11. added
    Issue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for development
    on Jul 10, 2017
  12. danielozano commented on Aug 7, 2017

    @danielozano

    Hi, we are getting this error on a EE 2.1.7.
    @DavidLambauer did you manage to write a workaround?
    If we force the cookie like shown here: #3676 (comment), we are able to use the store switcher 'correctly', but touching the index is not a good option for me.

    Thanks!

  13. hostep commented on Aug 7, 2017

    @hostep
    Contributor

    @danielozano, we ran into the same problem last week, we were able to fix it by applying MAGETWO-64885 on top of Magento CE 2.1.7, but then ran into a new issue, which I started documenting here: 508f1ef#commitcomment-23479499

    We worked around this new issue using this extra change for the magento/module-store module:

    diff --git a/Model/Store.php b/Model/Store.php
    index 7aa723ab123..e6cad7efb12 100644
    --- a/Model/Store.php
    +++ b/Model/Store.php
    @@ -1130,7 +1130,7 @@ class Store extends AbstractExtensibleModel implements
         public function getCurrentUrl($fromStore = true)
         {
             $sidQueryParam = $this->_sidResolver->getSessionIdQueryParam($this->_getSession());
    -        $requestString = $this->_url->escape(ltrim($this->_request->getRequestString(), '/'));
    +        $requestString = $this->_url->escape(ltrim($this->_request->getOriginalPathInfo(), '/'));
     
             $storeUrl = $this->getUrl('', ['_secure' => $this->_storeManager->getStore()->isCurrentlySecure()]);

    This extra workaround is only necessary for Magento 2.1.x, it works fine on the 2.2.0-develop branch without this workaround.

    Be aware, we still have to test this workaround properly, so no promises this won't break anything else.

  14. 4 remaining items

  15. added a commit that references this issue on Sep 13, 2017
  16. magento-engcom-team commented on Sep 20, 2017

    @magento-engcom-team
    Contributor

    @Noewt, thank you for your report.
    The issue is already fixed in 2.2.0

  17. duckchip commented on Oct 9, 2017

    @duckchip
    Contributor

    This merge created a new problem with the store switcher #11211

  18. ricoliv commented on Oct 29, 2017

    @ricoliv

    We need a stable store/language switcher in Magento 2.1.9 and had same problem as described by Noewt. It seems getTargetStorePostData() in .../switch/languages.phtml is the source of the problem. Since it looks like patches available still will need some good and thorough testing, we went for following temporary workaround in .../switch/languages.phtml

    <?php foreach ($this->getStores() as $_lang): ?>
        <?php if ($_lang->getCode() != 'default'): ?>
        <a class="lang-flag" href="<?php echo $_lang->getBaseUrl();?>" >
         <img border="0" alt="<?php echo $block->escapeHtml($_lang->getName()) ?>" src="<?php echo $this->getViewFileUrl('images/flags/flag_' . $_lang->getCode() . '.png');?>"></a>
        <?php endif;?>
    <?php endforeach;?>
    

    This requires setting individual Cookie Domains for each store.
    When switching between stores, each store will then have its own, dedicated shopping basket and switching always will redirect to home page (which is ok in our case).

    If there is anything wrong with this temporary workaround, pls let us know (we are no Magento experts).

    Thanks.

  19. artmouse commented on Jun 26, 2023

    @artmouse

    Preconditions (*)

    A vanilla installation of Magento 2.4.6-p1 with default settings.

    1. Set up Magento 2 multiple websites in sub directories
    2. The site exists and opens as / by default.
    3. The default language of the site is English.
    4. You need to add German language to the site (set up the multi-language store).
    5. The German language should be available as /de/.
    6. Setup instruction
    7. In the future the German store should open by default. (Make the German Store View the default).

    Stores and Web Site Configuration:

    Web Site information:

    • Name: Main Website
    • Code: base
    • Sort Order: 0
    • Default Store: Main Website Store

    Store information:

    • Name: Main Website Store
    • Code: main_website_store
    • Root Category: Default Category
    • Default Store View: English

    Steps to reproduce (*)

    Add second Store View and change the values of the main Store View for clarity

    English Store View (default) information:

    • Store: Main Website Store
    • Name: English
    • Code: en
    • Status: enabled
    • Sort Order: 10

    German Store View information:

    • Store: Main Website Store
    • Name: German
    • Status: enabled
    • Code: de
    • Sort Order: 20

    For the German store, you need to create a subdirectory in the pub, so that it can be accessed at /de/ and assign a proper URL.

    • Create a subdirectory /de/ in the pub.
    • Place the modified index.php in /de/ directory
    +$params = $_SERVER;  
    +$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE] = 'de';
    +$params[\Magento\Store\Model\StoreManager::PARAM_RUN_TYPE] = 'store';  
    +$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
    -$bootstrap = Bootstrap::create(BP, $_SERVER);
    • Allow NGINX to execute index.php file from the /de/ directory.
    # PHP entry point for main application
    +location ~ (index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ {
    -location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ {

    For Static and Media View Files, you will need to globally change the URL to something like this: https//domain.com/static/(media/) so that the styles would be available in /de/ as well.

    • Stores -> Configuration -> General -> Web (Scope: Default Config)
      • Base URLs
        • Base URL for Static View Files: https//domain.com/static/
        • Base URL for User Media Files: https//domain.com/media/
      • Base URLs (Secure)
        • Secure Base URL for Static View Files: https//domain.com/static/
        • Secure Base URL for User Media Files https//domain.com/media/

    Specify a URL for the German store with the prefix /de/.

    • Stores -> Configuration -> General -> Web (Scope: German Store View)
      • Base URLs
        • Base Link URL: https//domain.com/de/
      • Base URLs (Secure)
        • Base Link URL: https//domain.com/de/

    Change the main Store View for Store to German. (make it default)

    • Stores -> Settings -> All Stores -> Store (Main Website Store)
      • Change Default Store View: en -> de

    Going to the site...

    • Now by default we are redirected to /de/ and the site opens in German (Default, Store View Code: de). Great!
    • The site also displays a language switcher.
    • Switching to English (Store View Code: en) - redirect to / and the language changes.
    • Switch back to German (Default, Store View Code: de) - redirect to /de/ but language does not change, English remains. In the same way all store URLs without the prefix /de/.

    Expected result (*)

    There is no "store" cookie for the primary Store View.
    When the primary Store View (de) is located on the /de/ path and when you switch to another Store View (en) that is located on the / path, the "store" cookie is set for the target Store View (en).

    Name Value Domain Path
    store en .domain.com /

    And when switching from another Store View (en) when the "store" cookie is already set, it checks to match the target Store View with the default Store View ID.
    If there is a match, the "store" cookie should be removed.

    public function switch(StoreInterface $fromStore, StoreInterface $targetStore, string $redirectUrl): string
    {
    $defaultStoreView = $this->storeManager->getDefaultStoreView();
    if ($defaultStoreView !== null) {
    if ($defaultStoreView->getId() === $targetStore->getId()) {
    $this->storeCookieManager->deleteStoreCookie($targetStore);
    } else {
    $this->httpContext->setValue(Store::ENTITY, $targetStore->getCode(), $defaultStoreView->getCode());
    $this->storeCookieManager->setStoreCookie($targetStore);
    }
    }
    return $redirectUrl;
    }

    But when try to delete the store cookie in $cookieMetadata set the path /de, but existing "store" cookie has path /.

    public function deleteStoreCookie(StoreInterface $store)
    {
    $cookieMetadata = $this->cookieMetadataFactory->createPublicCookieMetadata()
    ->setPath($store->getStorePath());
    $this->cookieManager->deleteCookie(self::COOKIE_NAME, $cookieMetadata);
    }

    getStorePath() returns /de, but the "store" cookie has a path / - perhaps because of this the "store" en cookie is not deleted and the site always stays on Store View (en)

    public function getStorePath()
    {
    // phpcs:ignore Magento2.Functions.DiscouragedFunction
    $parsedUrl = parse_url($this->getBaseUrl());
    return $parsedUrl['path'] ?? '/';
    }

    Actual result (*)

    1. When the primary Store View (de) is located on the /de/ path and when you switch to another Store View (en) that is located on the / path, the "store" cookie is set for the target Store View (en).
    2. And when switching from another Store View (en) when the "store" cookie is already set, it checks to match the target Store View with the default Store View ID.
    3. If there is a match, the "store" cookie should be removed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Fixed in 2.2.xThe issue has been fixed in 2.2 release lineIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentReproduced on 2.1.xThe issue has been reproduced on latest 2.1 releasebug report

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions