如何检查客户是否已在magento 2中登录?


64

如何在Magento 2中查找客户是否登录。

如果客户已登录,那么如何从会话中获取客户数据?


这里提到的解决方案都不适合我。@Rakesh:您能分享一下它对您的工作方式吗?
Ipsita Rout

请记住,如果您需要从Magento JS模块(text/x-magento-init)中检查登录状态,则可以避免ObjectManager实例化并将状态传递给模块的config对象,从而从中查询登录链接,从而节省一些开销。 JS模块中,例如:var isLoggedIn = $('.authorization-link > a').attr('href').indexOf('/login')<0;
thdoan


1
下一行在做什么?var isLoggedIn = $('。authorization-link> a')。attr('href')。indexOf('/ login')<0;
Jaisa

Answers:


61

以下代码可以检查客户登录或不在任何地方

$ objectManager = \ Magento \ Framework \ App \ ObjectManager :: getInstance();
$ customerSession = $ objectManager-> get('Magento \ Customer \ Model \ Session');
if($ customerSession-> isLoggedIn()){
   //客户登录操作
}

从控制器

$ this-> _ objectManager-> get('Magento \ Customer \ Model \ Session');
if($ customerSession-> isLoggedIn()){
   //客户登录操作
}

1
当然,这是最明显的解决方案,我是第一次使用它,但是后来我注意到,如果尚未初始化客户会话,它就无法正常工作,因此我找到了一个不太明显但更可持续的解决方案。
Mage2.PRO 2015年

11
一个不应该直接使用objectmanager。只需为会话模型注入ObjectFactory生成的代码即可。
CarComp '16

6
请不要在答案中复制其他答案。
马吕斯

6
这是“错误”的方式,拉斐尔在数字钢琴家的答案是最不正确的答案
洛伦佐

1
如果您启用了全页缓存,并且在块/模板中调用了此方法,则该方法将不起作用,因为客户会话将始终返回空。使用http上下文进行检查。
leo

84

重要提醒:永远不要直接调用对象管理器

因此,这是干净的方法

在除模板之外的任何类中

您首先需要在构造函数中注入以下类/Magento/Customer/Model/Session

protected $_session;

public function __construct(
    ...
    \Magento\Customer\Model\Session $session,
    ...
) {
    ...
    $this->_session = $session;
    ...
}

然后,在您的课程中,您可以调用以下命令:

if ($this->_session->isLoggedIn()) {
    // Customer is logged in 
} else {
    // Customer is not logged in
}

在模板中

它需要在模板中做更多的工作,因为您将必须为呈现模板的块设置一个首选项,从而以一种干净的方式进行操作:

<preference for="Block\That\Renders\The\Template"
            type="Vendor\Module\Block\Your\Custom\Block" />

然后,在您的自定义块构造器中,您需要遵循与任何类相同的依赖项注入(上面已说明)。

此处额外步骤是创建可在模板中使用的公共方法,以检查客户是否已登录

public function isCustomerLoggedIn()
{
    return $this->_session->isLoggedIn();
}

然后,您可以在模板中调用:

if ($block->isCustomerLoggedIn()) {
    // Customer is logged in
} else {
    // Customer is not logged in
}

如果客户会话尚未初始化,则选择

还有另一种方式,这意味着使用Magento\Framework\App\Http\Context而不是Magento/Customer/Model/Session

然后,您可以致电$this->_context->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH)而不是$this->_session->isLoggedIn()检查客户是否已登录。

但是,此方法可能会给您带来不同的结果,建议您阅读以下出色的答案以获取更多信息:https : //magento.stackexchange.com/a/92133/2380


<preference ... />标签应放在自定义主题中的何处?什么是确切Block\That\Renders\The\TemplateVendor\Module\Block\Your\Custom\Block
安德里亚(Andrea)

@Andrea很好,这取决于每个案例的情况。这就是为什么我在回答中使用通用类路径名的原因
拉斐尔(Raphael)在Digital Pianism上

我有一个自定义块,定义为class Html extends \Magento\Framework\View\Element\Template可以在构造函数中注入会话对象的位置。我以这种方式(来自布局xml文件)在我的自定义主题中使用了此块:<block class="Vendor\ThemeName\Block\Html" template="Vendor_ModuleName::html/my-custom-template.phtml"/>。我想检查模板文件中的登录用户my-custom-template.phtml。我应该如何使用`<preference ... />标记?
安德里亚(Andrea)

对我不起作用-> isLoggedin()方法。我不知道为什么,但它永远不会返回客户已登录,实际上是!它已登录(我已登录)。
弗拉基米尔·德斯波托维奇

@VladimirDespotovic是否测试了替代方法?
拉斐尔(Raphael)在Digital Pianism上2017年

31

可以通过Magento\Framework\App\Http\Context或通过Magento\Customer\Model\Session。但是,结果可能会有所不同:

  • HTTP上下文的初始化要早于客户会话(但没关系,因为两者都是在操作控制器中初始化的)
  • PageCache模块打开时(可能始终在生产中),请记住,一旦开始生成布局,就会\Magento\PageCache\Model\Layout\DepersonalizePlugin::afterGenerateXml在所有可缓存页面上清除客户会话。这意味着如果您现在检查客户是否通过HTTP上下文登录,它仍将显示“是”,但是客户数据将不再在客户会话中可用。因此,在尝试访问客户会话中的数据之前,必须仔细检查。这很容易在代码块中发生,但在动作控制器中不太可能发生,因为您不希望在那里手动生成布局,但它将在动作控制器返回的实例后生成。ResultInterface

为了消除打开PageCache时描述的任何不一致的风险,请考虑使用客户会话(如果已初始化)(对于动作控制器为true)。否则使用HTTP上下文。


启用PageCache的重要提示,谢谢
LucScu

3
@Alex我正在使用以下代码$ customerSession = $ objectManager-> get('Magento \ Framework \ App \ Http \ Context'); $ isLoggedIn = $ customerSession-> getValue(\ Magento \ Customer \ Model \ Context :: CONTEXT_AUTH); 但是由于启用了缓存,因此它显示“登录”选项而不是“登录”以登录客户。我该如何解决?
Nitesh

这让我们大吃一惊,谢谢。您的答案需要更多注意:-)在生产中启用缓存会使会话困难。如果要编写自定义的magento插件,请将cachable = false放置在路由的XML文件中。
Ligemer '17

2
你为什么要把cachable = false?
LucScu

15
/** @var \Magento\Framework\App\ObjectManager $om */
$om = \Magento\Framework\App\ObjectManager::getInstance();
/** @var \Magento\Framework\App\Http\Context $context */
$context = $om->get('Magento\Framework\App\Http\Context');
/** @var bool $isLoggedIn */
$isLoggedIn = $context->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);

那么如何获取custommer是登录@ Mage2.PRO?
xanka

8
您永远不要直接使用ObjectManager
7ochem '16

是的,同意。Objectmanager不是要走的路。将CustomerFactory注入类构造函数中。
CarComp

上面的解决方案对我不起作用
Ipsita Rout

@lpsita让我知道您是否遇到这个问题?我刚刚修复了它:)
杰伊(Jai)2015年

10

这些解决方案都不适合我。有些页面似乎已登录,而其他页面则没有。看来这是错误:

https://github.com/magento/magento2/issues/3294

我最终创建了一个可以在模板中调用的助手:

<?php
namespace MyVendor\MyModule\Helper;

use Magento\Framework\App\Helper\AbstractHelper;

/**
 * Created by Carl Owens (carl@partfire.co.uk)
 * Company: PartFire Ltd (www.partfire.co.uk)
 **/
class Data extends AbstractHelper
{
    /**
     * @var \Magento\Framework\App\Http\Context
     */
    private $httpContext;

    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Framework\App\Http\Context $httpContext
    ) {
        parent::__construct($context);
        $this->httpContext = $httpContext;
    }

    public function isLoggedIn()
    {
        $isLoggedIn = $this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
        return $isLoggedIn;
    }
}

然后,可以在模板中使用该帮助器,如下所示:

<?php
$helper = $this->helper('MyVendor\MyModule\Helper\Data');

if ($helper->isLoggedIn()) {
    //show something
}

没错,对我有用的唯一代码是您的代码。谢谢!
乔治·乔治,

我如何->getCustomer()->getName()使用上下文进行调用,因为如果使用会话,则不适用于所有页面。
乔治·乔治

如果启用了全页缓存,这是正确的答案。您可以先检查customersession,如果返回false,则可以执行此操作
CompactCode

9

要使用户登录模板,您只需在一行中简单地调用helper即可:

<?php $_loggedin = $this->helper('Magento\Checkout\Helper\Cart')->getCart()->getCustomerSession()->isLoggedIn(); ?>

<?php if( $_loggedin ) : ?>

     <div><!-- add your code --></div>

<?php endif; ?>

无需使用objectmanager的不错的解决方案。
Nitesh

2
在v2.1.5中,在生产模式下启用FPC和Varnish的情况下,此功能不起作用。
thdoan '17

8

在生产模式下启用了全页缓存和清漆的情况下,这里的所有解决方案都无法在Magento v2.1中对我可靠地起作用。我终于找到了一种解决方案,该解决方案从获得灵感后就可以在100%的时间内启用所有缓存vendor/magento/module-theme/view/frontend/templates/html/header.phtml。这是我的解决方案,它在用户注销时显示“登录”链接,在用户登录时显示“登录”链接:

<li data-bind="scope: 'customer'">
  <!-- ko if: customer().firstname  -->
  <a href="<?php echo $this->getUrl('customer/account/logout'); ?>" style="display:none;" data-bind="style: {display:'inline'}"><?php echo __('Sign Out') ?></a>
  <!-- /ko -->
  <!-- ko ifnot: customer().firstname  -->
  <a href="<?php echo $this->getUrl('customer/account/login'); ?>" style="display:none;" data-bind="style: {display:'inline'}"><?php echo __('Sign In') ?></a>
  <!-- /ko -->
  <script type="text/x-magento-init">
  {
    "*": {
      "Magento_Ui/js/core/app": {
        "components": {
          "customer": {
            "component": "Magento_Customer/js/view/customer"
          }
        }
      }
    }
  }
  </script>
</li>

更新:自v2.1.5起,此解决方案不再可靠。有关解决方案,请参见问题9156


这是一个很好的解决方案。虽然可以在布局文件中使用cachable =“ false”。
Dinesh Yadav

我已经cachable="false"在该块的布局XML中使用了,但是清漆显然仍在对其进行缓存。不确定这是否是错误,但是淘汰赛是规避此问题的好方法。唯一的缺点是由于KO绑定,在显示“登录/注销”链接之前会稍有延迟。
thdoan

6

那里有很多答案,像这样...

获取对象管理器加载类模型

这是在Magento2.0中使用的WRONG方法。在2.0中,自动生成的对象工厂是必经之路。您可以将它们注入几乎任何类的构造函数中并使用它们。例:

public function __construct(
            Context $context,
            CollectionFactory $cmspageCollectionFactory,
            array $data = [],
            CustomerFactory $customerFactory,
            SessionFactory $sessionFactory)
        {
            parent::__construct($context, $data);
            $this->_cmspageCollectionFactory = $cmspageCollectionFactory;
            $this->customerFactory = $customerFactory;
            $this->sessionFactory = $sessionFactory;
        }

        /**
         * @return \Stti\Healthday\Model\ResourceModel\Cmspage\Collection
         */
        public function getCmspages()
        {
            // First check to see if someone is currently logged in.
            $customerSession = $this->sessionFactory->create();
            if ($customerSession->isLoggedIn()) {
                // customer is logged in;
                //$customer = $this->customerFactory->create()->get
            }

2
如果工厂出错,则使用完整路径,例如\Magento\Customer\Model\SessionFactory $sessionFactory
thdoan '17

正确。我通常在顶部声明它们,只是这样我的方法看起来不会像是一团糟:)
CarComp

3

您好在这里得到答案:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->create('Magento\Customer\Model\Session');

if ($customerSession->isLoggedIn()) {
    $customerSession->getCustomerId();  // get Customer Id
    $customerSession->getCustomerGroupId();
    $customerSession->getCustomer();
    $customerSession->getCustomerData();

    echo $customerSessionget->getCustomer()->getName();  // get  Full Name
    echo $customerSessionget->getCustomer()->getEmail(); // get Email
}

来源

$customerSession = $objectManager->get('Magento\Customer\Model\Session');

用create代替get现在可以正常工作:

$customerSession = $objectManager->create('Magento\Customer\Model\Session');

4
您永远不要ObjectManager直接使用
7ochem

仅当禁用缓存而不启用缓存时才有效。
杰伊

@Jai,这对我的开发和生产也是如此。请您向我发送重现该问题的步骤吗?
Manish

我必须检查用户是否登录。但是下面的代码仅在禁用的缓存中起作用$ objectManager = \ Magento \ Framework \ App \ ObjectManager :: getInstance(); $ customerSession = $ objectManager-> create('Magento \ Customer \ Model \ Session'); if($ customerSession-> isLoggedIn()){// CODE}
Jai

在启用缓存中:仅适用于自定义仪表板页面,不适用于主页和网站的其他页面。我的问题:magento.stackexchange.com/q/177964/29175
Jai

3

这也是解决方案“检查客户是否已登录Magento2”之一。

试试下面的代码:

 $om = \Magento\Framework\App\ObjectManager::getInstance();
 $context = $om->get('Magento\Framework\App\Http\Context');
 $isLoggedIn = $context->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
 if($isLoggedIn){
      echo "Yes Customer loggedin";
      echo "<pre>";print_r($context->getData()); 
 }

2

试试下面的代码:

<?php
namespace YourCompany\ModuleName\Helper;

class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Customer\Model\Session $customerSession
    ) {
        $this->customerSession = $customerSession;
        parent::__construct($context);
    }

public function isLoggedIn() // You can use this fucntion in any phtml file
    {
        return $this->customerSession->isLoggedIn();
    }
}

要在phtml文件中使用上述代码,您可以按以下方式调用isLoggedIn()函数:

<?php $helper = $this->helper('YourCompany\ModuleName\Helper\Data'); ?>
<?php if($helper->isLoggedIn()) : ?>
    logged in
<?php else : ?>
    not logged in
<?php endif; ?> 

希望这个帮助谢谢。


嗨,@ Shubdham,它无法正常工作..
jafar pinjar

这是一个很好的解决方案。谢谢
Ask Bytes

是的,希望对您有所帮助。
Shubham Khandelwal

2

我有最好的解决方案。它基于客户的身份验证。在某些情况下,客户会话无法正常工作,但是每次我的解决方案都能正常工作时。让我们来看看。

<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->get('Magento\Customer\Block\Account\AuthorizationLink');
if ($customerSession->isLoggedIn() == true) {
//your code.
} ?>

谢谢。


1

当前可行的解决方案(IMHO)

<?php

namespace My\Module\Helper\Data;

/**
 * @var \Magento\Framework\ObjectManagerInterface
 */
protected $objectManager;

/**
 * @var \Magento\Customer\Model\SessionFactory
 */
protected $customerSession;

/**
 * Class Data
 */
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
    /**
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     */
    public function __construct(
         \Magento\Framework\ObjectManagerInterface $objectManager
    )
    {
        $this->objectManager   = $objectManager;
        $this->customerSession = $this->objectManager->create('Magento\Customer\Model\SessionFactory')->create();
    }

    /**
     * @return \Magento\Customer\Model\SessionFactory
     */
    public function getCustomerSession()
    {
       return $this->customerSession;     
    }

    /**
     * @return bool
     */
    public function isCustomerLoggedIn()
    {
        return ($this->getCustomerSession()->isLoggedIn()) ? true : false;
    }
}

1

如果要检查是否已登录客户,请在phtml文件中使用此代码,

$om = \Magento\Framework\App\ObjectManager::getInstance();
$appContext = $om->get('Magento\Framework\App\Http\Context');
$isLoggedIn = $appContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
if($isLoggedIn) {
    /** LOGGED IN CUSTOMER, this should work in template   **/
}

2
永远不要ObjectManager直接使用模板,也永远不要使用这种类型的代码。您应该在块类中创建功能来管理此功能。
7ochem

一旦知道如何正确执行操作,您就会想知道您的经理是如何以其他方式完成操作的!
CarComp

0
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->get('Magento\Customer\Model\Session');

if($customerSession->isLoggedIn()) {

}

0

另一个答案:

<?php $_loggedin = $block->getLayout()->createBlock('Magento\Customer\Block\Account\AuthorizationLink')->isLoggedIn() ?>
 <?php if( $_loggedin ) : ?>
   // your code
 <?php endif; ?>

你怎么看?


0

如果要在启用Magento默认FPC缓存后想要使用会话模型,则无法从会话模型中获取记录的状态,在这种情况下,您应该使用SessionFactory。

如果启用了FPC缓存,则不会启动会话,详细信息:https : //github.com/magento/magento2/issues/3294#issuecomment-328464943

要解决此问题,您必须使用SessionFactory,例如:

/**
* @var \Magento\Customer\Model\Session
*/
protected $_customerSessionFactory;

public function __construct(
    ....
    \Magento\Customer\Model\SessionFactory $customerSessionFactory
    ....
) 
{
    ....
    $this->_customerSessionFactory = $customerSessionFactory;
    ....
}

public function getCustomerId(){
  $customer = $this->_customerSessionFactory->create();
  echo $customer->getCustomer()->getId();
}

-1

我尝试了许多在google上找到的方法,但是没有一种解决方案有效。因此,我检查了核心功能并创建了一个php文件,以检查是否已在不使用对象管理器的情况下登录了客户。


            / **
         *客户会议
         *由Web技术代码创建的模块
         *由Vinay Sikarwar开发
         * @var \ Magento \ Framework \ App \ Http \ Context
         * /
        受保护的$ session;

        / **
         *注册构造函数。
         * @param上下文$ context
         * @参数数组$ data
         * /
        公共功能__construct(
            上下文$ context,
                    \ Magento \ Framework \ Session \ Generic $ session,
            数组$ data
        )
        {
                    $ this-> _ session = $ session;
                    parent :: __ construct($ context,$ data);
        }

            / **
         *检查客户登录状态
         *
         * @api
         * @返回布尔
         * /
        公共函数isCustomerLoggedIn()
        {
            return(布尔)$ this-> getCustomerId()
                && $ this-> checkCustomerId($ this-> getId())
                &&!$ this-> getIsCustomerEmulated();
        }
    }

有关更多信息,请在此处进行检查http://blog.webtechnologycodes.com/customer-loggedin-check-magento2

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.