不安定なCookie関連のログインの問題


8

これは長いです...

間違ったCookie管理が原因でログインが失敗するという悪いケースがあります。まず、私は顧客がカタログを表示する前にログインする必要があるクローズドストア(B2B)を管理しています。未登録のアクセスはすべてログインページにリダイレクトされますが、ユーザー名とパスワードが正しい場合でも、顧客がログインできないことがあります。Diglin_Username拡張機能とStoreRestricitionプラグインを使用して目的の動作を実現するため、「ユーザー名」と言います。ときどき、Magentoが残した2つの異なるCookieのセットが見つかり、それらが2つの異なるドメイン(たとえば、.www.abc.comと.abc.com)を参照していることがあります。

初期のセッションのインスタンス化に関する偉大なAlan Stormからのこの記事を読んだ後、私のブラウザーで恐ろしいPHPSESSID Cookieを見つけた後、問題を詳細に調査しました。

私が見つけたのは両面です。まず、Mage_Core_Model_Session_Abstract_Varienクラスの関数start()にMage :: Log()呼び出しを入れて、Magentoが新しいセッションを開始するために行ったさまざまな試行をログに記録し、最初のMage :: run()の呼び出しに続いてpreDispatch()を呼び出したことに気付きました、Mage_Core_Controller_Front_Actionクラスのdispatch()およびpostDispatch()メソッドは通常のシーケンスで呼び出されますが、postDispatch()を実行すると、preDispatch()によって開始されたセッションを見つけられず、新しいセッションの作成に進むようです。この点で、Magento 1.7.xと1.8.xのバージョンのコードに違いがあり、問題を解決できる可能性があると思います。

Magento 1.7.x-Mage_Core_Model_Session_Abstract_Varienクラス:

public function start($sessionName=null)
{
    if (isset($_SESSION)) {
        return $this;
    }
    .
    .
}

Magento 1.8.x-Mage_Core_Model_Session_Abstract_Varienクラス:

public function start($sessionName=null)
{
    if (isset($_SESSION) && !$this->getSkipEmptySessionCheck()) {
        return $this;
    }
    .
    .
}

SkipEmptySessionCheckプロパティを設定する場所が見つからないので、Mage_Core_Controller_Front_Actionクラスに次のようにパッチを適用しました。

public function postDispatch()
{
    parent::postDispatch();
    if (!$this->getFlag('', self::FLAG_NO_START_SESSION )) {
        if (session_id()) {
            Mage::getSingleton('core/session')->setLastUrl(Mage::getUrl('*/*/*', array('_current'=>true)));
        }
    }
    return $this;
}

すでに開始されているセッションが見つからない場合、postDispatch()がMage :: getSingleton( 'core / session')を呼び出さないようにします(新しいセッションが作成されます)。PHPSESSID Cookieが完成してすべてが完了するまで、私は...

しかし、そうではありません。今、私はPHPSESSID Cookieを取り除きましたが、ブラウザに保存された2つの異なるCookieのセットに(不規則に)移動します。間違ったCookieを削除するだけでログインに成功するか、メッセージも表示されずにログインページにリダイレクトされます。システム構成でCookieドメインを明示的に指定しようとしましたが、これで問題は解決しませんでした。

再びコードベースの奥深くで、MagentoがCookieを設定するとき、さまざまな場所で、Mage_Core_Model_Cookieクラスの関数getDomain()から使用するドメインを取得することがわかりました。

public function getDomain()
{
    $domain = $this->getConfigDomain();
    if (empty($domain)) {
        $domain = $this->_getRequest()->getHttpHost();
    }
    return $domain;
}

さて、ブラウザでMagentoから取得したページを見ると、 'head'セクションで次のようになっています。

<script type="text/javascript">
//<![CDATA[
Mage.Cookies.path     = '/';
Mage.Cookies.domain   = '.www.abc.com';
//]]>
</script>

これらの行はapp / design / frontend / base / default / template / page / js / cookie.phtmlから取得されます。

<script type="text/javascript">
//<![CDATA[
Mage.Cookies.path     = '<?php echo $this->getPath()?>';
Mage.Cookies.domain   = '<?php echo $this->getDomain()?>';
//]]>
</script>

次に、このコードはMage_Page_Block_Js_CookieクラスのgetDomain()関数を参照します。

public function getDomain()
{
    $domain = $this->getCookie()->getDomain();
    if (!empty($domain[0]) && ($domain[0] !== '.')) {
        $domain = '.'.$domain;
    }
    return $domain;
}

たとえば、システム構成でcookieドメインを「www.abc.com」として設定すると、次のようになります。

Mage.Cookies.domain   = '.www.abc.com'

私のブラウザーで「www.abc.com」と「.www.abc.com」の両方のCookieを見つけると、「わかりました。システム設定で「.abc.com」を設定し、常に「 .abc.com 'クッキー!! "...

しかし、方法はありません。HTMLページで常に「.abc.com」を取得していますが、それでも不規則に「www.abc.com」のCookieが取得され、ログインできません。

私は困惑し、私の顧客は私が思っていたほど私は良くないと思っ始めています(私もそう思い始めています...):(

君たちの何人か(そしてギャル)は何かヒントを持っていますか?

更新: セッションとCookieに関する問題が、MagentoのキャッシュとしてVarnishを使用することに関連している誰かを見たことがあります。私もVarnishを使用しているので、無効にすると問題が解決するかどうか試してみます。


こんにちはマリウス、なぜ編集?フォーラムのルールに違反していますか?
slamarca 2014

問題は再現できないことを除いて、同じ動作(ログインと顧客がセッションを失う)が発生しています。これは、問題の解決はもちろんのこと、トラブルシューティングのあらゆる試みを本当に複雑にします。どのようにして問題を確実に再現しましたか?@サンダーマンジェル-それはただのことです、私は問題を再現することができなかったので、異なるCookieがどのように見えるのか確信が持てません。問題を解決するために加えられた修正を検証できるように再現できれば、もっと幸せになります。問題を再現する方法について、正しい方向に向けてくれる方がいらっしゃれば幸いです。ありがとう!

@Zhulak wwwと同じ問題。と非www。クッキー?
サンダーマンゲル

回答:


8

これはNovusWebの記事です:http ://www.novusweb.com/fix-for-passing-magento-session-ids/

MagentoセッションIDを渡すための修正

著者:ブレットウィリアムズ

2011年11月9日投稿

MagentoセッションIDの修正

eコマースサイトを構築するときは、共有SSLをよく使用します。これは、サイトごとに個別のSSL証明書を購入することなく、複数のストアをホストする便利な方法です。ほとんどのeコマースクライアントは、単一のMagentoまたはOpenCartインストール内の複数のストアを管理しています。最近、Magentoに問題が見つかりました。これは、顧客のセッションIDが、サイトへの最初の訪問と、登録済みの顧客としてストアにログインした後のページビューとの間で正常に渡されなかったためです。Magentoが同じセッションIDを渡さなかったため、以前にログインして商品をカートに追加したことがある顧客が、後で戻ってログインした後にカートの内容を失うことになります。これは素晴らしい状況ではありません。

セッション中に作成されたCookieを確認すると、安全でないドメイン(http://)から安全なドメイン(https://)に移動すると、セッションIDが正常に渡され、新しいセキュアドメインのCookieは、非セキュアドメインと同じセッションIDで作成されました。ただし、顧客がログインすると、完全に新しいセッションIDを持つセキュアなドメイン用の新しいCookieが作成されました。Magentoは新しいCookieを使用していたため、顧客が安全でないドメインページ(製品の詳細ページなど)に戻るたびにクリックすると、安全ではないドメインが新しいCookie /セッションIDを使用していないため、Magentoにログインしなくなりました。ログイン時に作成されたセッションID。解決策は、新しいセッションIDが作成されている場所を見つけて、それが発生しないようにすることです。

そこで、Magentoが新しいセッションを作成している場所を見つけることができるかどうかを確認するために、コードを掘り下げ始めました。

app / code / core / Mage / Customer / Model / session.phpの177行から189行(Magento CE 1.5.1)でこれを見つけました:

public function login($username, $password)
{
/** @var $customer Mage_Customer_Model_Customer */
$customer = Mage::getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId());

if ($customer->authenticate($username, $password)) {
    $this->setCustomerAsLoggedIn($customer);
    $this->renewSession();
    return true;
}
return false;
}

私の解決策は、行$ this-> renewSession():をコメント化することでした。これにより、顧客がログインしたときにMagentoが新しいセッションを作成しません。変更されたコードは次のようになります。

public function login($username, $password)
{
/** @var $customer Mage_Customer_Model_Customer */
$customer = Mage::getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId());

if ($customer->authenticate($username, $password)) {
    $this->setCustomerAsLoggedIn($customer);
    //$this->renewSession();
    return true;
}
return false;
}

これまでのテストでは、すべてが正常に機能しており、顧客のセッションはドメイン間で保持されています。さて、このコアファイルを急いで変更する前に、次のことを行ってください。

データベースをバックアップします(変更を行う前に必ずこれを行う必要があります)。次のディレクトリ階層を構築します:app / code / local / Mage / Customer / Model /。この新しいディレクトリにsession.phpのコピーを置きます。上記の適切な行をコメント化して、ファイルを保存します。変更をapp / code / localディレクトリに置くことで、コアファイルの代わりにこれらのファイルを使用するようにMagentoに指示しています。さらに重要なことは、将来Magentoを更新した場合でも、変更内容が失われないようにすることです。

また、変更したファイルをapp / code / localディレクトリに保存するだけでよいので、コードの変更を保存および管理する便利な方法も提供します。

よりエレガントな解決策を知っている場合、またはこれが機能するか機能しない場合は、コメントを残してください。


4
に保存されてapp/code/local/Mage/*いる変更の場合。Magentoをアップグレードする前に、インストーラーからコードを抽出し、変更したコードと比較して、コードが異なるかどうかを確認します。その場合は、アップグレード後に配置する新しいバージョンを変更します。内容に互換性のない変更があるため、アップグレード時にサイトをフォールバックするためにそれを保持しておくようなものはありません。
Fiasco Labs

3
同意した。この記事は$this->renewSession();setCustomerAsLoggedIn()機能に移行したため、1.8以前のインストールにのみ適用されます。
seanbreeden 2014

1
より最新のMagentoバージョンについては、「renewSession()」を検索するだけでcode/core/Mage/Core/Model/Session/Abstract.phpcode/core/Mage/Admin/Model/Session.phpコメントアウトできる場所にあります。もちろん、モデルのローカルコピーです。@FiascoLabsはさらに優れており、変更する必要のある関数のみを適切にオーバーライドし、残りのファイルをコアにそのまま残します:)
WackGet

1
これは、トラブルシューティングを3週間試みた後、4年後に私たちを助けてくれました。Amasty FPCをインストールしてサーバーの負荷テストを行ったところ、問題が明らかになりました(Magento 1.9.3.2)。つまり、Facebookや通常のログインでログインできず、サーバーに負荷がかかっているときにカートに追加できません。その後、負荷がなくても問題が発生しました。現在、問題のような問題は現在、回答に従って解決されているようです。@seanbreedenに感謝します。あなたは非常に疲れた開発者に新しい命を吹き込みました。<3
アリ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.