Jak sprawdzić, czy klient jest zalogowany w Magento 2?

64

Jak sprawdzić, czy klient jest zalogowany, czy nie w Magento 2.

Jeśli klient jest zalogowany, to jak uzyskać dane klienta z sesji?

Rakesh Jesadiya
źródło
żadne z wymienionych tutaj rozwiązań nie działało dla mnie. @Rakesh: czy mógłbyś podzielić się tym, jak to dla ciebie działało?
Ipsita Rout
Należy pamiętać, że jeśli kiedykolwiek będziesz musiał sprawdzić status zalogowanego modułu Magento JS ( text/x-magento-init), możesz zaoszczędzić trochę pieniędzy, unikając tworzenia instancji ObjectManager i przekazując status do obiektu konfiguracyjnego modułu, zamiast tego pytając o link logowania z w module JS, np .:var isLoggedIn = $('.authorization-link > a').attr('href').indexOf('/login')<0;
thdoan 12.10.16
1
Co robi poniższy wiersz? var isLoggedIn = $ ('. autoryzacja-link> a'). attr ('href'). indexOf ('/ login') <0;
Jaisa
Sprawdź link, rakeshjesadiya.com/…
Rakesh Jesadiya

Odpowiedzi:

62

Po kodzie możesz sprawdzić login klienta lub nigdzie

$ objectManager = \ Magento \ Framework \ App \ ObjectManager :: getInstance ();
$ customerSession = $ objectManager-> get ('Magento \ Customer \ Model \ Session');
if ($ customerSession-> isLoggedIn ()) {
   // akcja logowania klienta
}

Z kontrolera

$ this -> _ objectManager-> get ('Magento \ Customer \ Model \ Session');
if ($ customerSession-> isLoggedIn ()) {
   // akcja logowania klienta
}
Sohel Rana
źródło
1
Oczywiście jest to najbardziej oczywiste rozwiązanie i zastosowałem je po raz pierwszy, ale zauważyłem, że nie działa ono poprawnie, gdy sesja klienta nie została jeszcze zainicjowana, więc znalazłem mniej oczywiste, ale bardziej zrównoważone rozwiązanie.
Mage2.PRO,
11
Nie należy używać bezpośrednio menedżera obiektów. Wystarczy wstrzyknąć wygenerowany kod ObjectFactory dla modelu sesji.
CarComp
6
proszę nie kopiuj innych odpowiedzi w swojej odpowiedzi.
Marius
6
to jest „zły” sposób, odpowiedź Raphaela z Digital Pianism jest rygorystyczna
Lorenzo
1
Jeśli włączyłeś pełną pamięć podręczną strony i wywołujesz ją w bloku / szablonie, to nie działa, ponieważ sesja klienta zawsze zwróci pustą. Zamiast tego użyj kontekstu HTTP, aby to sprawdzić.
leo
84

Ważne przypomnienie: Nigdy nie należy bezpośrednio wywoływać Menedżera obiektów

Oto jak to zrobić w czysty sposób

W dowolnej klasie oprócz szablonów

Najpierw musisz wstrzyknąć następującą klasę do swojego konstruktora /Magento/Customer/Model/Session:

protected $_session;

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

Następnie w klasie możesz zadzwonić:

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

W szablonie

Wymaga nieco więcej pracy w szablonie, ponieważ będziesz musiał ustawić preferencje dla bloku, który renderuje szablon, aby zrobić to w czysty sposób:

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

Następnie w niestandardowym kontrolerze bloków musisz wykonać ten sam wstrzyknięcie zależności, jak dla każdej klasy (wyjaśnione powyżej).

Dodatkowy krok tutaj jest stworzenie metody publiczne, które mogą być użyte w szablonie, by sprawdzić, czy klient jest zalogowany, czy nie

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

Następnie w swoim szablonie możesz zadzwonić:

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

Alternatywnie, jeśli sesja klienta nie została jeszcze zainicjowana

Jest inny sposób na zrobienie tego, który wymaga użycia Magento\Framework\App\Http\ContextzamiastMagento/Customer/Model/Session

Następnie możesz zadzwonić $this->_context->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH)zamiast $this->_session->isLoggedIn()sprawdzić, czy klient jest zalogowany, czy nie.

Jednak ta metoda może dać różne wyniki , sugeruję przeczytanie tej wspaniałej odpowiedzi, aby uzyskać więcej informacji: https://magento.stackexchange.com/a/92133/2380

Raphael at Digital Pianism
źródło
Gdzie należy umieścić <preference ... />tag w niestandardowym motywie? Jakie są dokładnie Block\That\Renders\The\Templatei Vendor\Module\Block\Your\Custom\Block?
Andrea,
@ Andrea dobrze to zależy i jest różna dla każdego przypadku. Właśnie dlatego użyłem ogólnych nazw ścieżek klas w mojej odpowiedzi
Raphael z Digital Pianism
Mam niestandardowy blok zdefiniowany jako miejsce, w class Html extends \Magento\Framework\View\Element\Templatektórym mogę wstrzyknąć obiekt sesji do konstruktora. Używam tego bloku w moim niestandardowego tematu w ten sposób (z plików XML szablonu) <block class="Vendor\ThemeName\Block\Html" template="Vendor_ModuleName::html/my-custom-template.phtml"/>. Chciałbym sprawdzić zalogowanego użytkownika w pliku szablonu my-custom-template.phtml. Jak powinienem używać znacznika `<preferencje ... />?
Andrea,
Dla mnie nie działa metoda -> isLoggedin (). Nie wiem dlaczego, ale nigdy nie zwraca, że ​​klient jest zalogowany i faktycznie tak jest! Jest zalogowany (jestem zalogowany).
Vladimir Despotovic
@VladimirDespotovic przetestowałeś alternatywną metodę?
Raphael w Digital Pianism
31

Jest to możliwe za pośrednictwem Magento\Framework\App\Http\Contextlub za pośrednictwem Magento\Customer\Model\Session. Wynik może być jednak inny:

  • Kontekst HTTP jest inicjowany wcześniej niż sesja klienta (ale to nie ma znaczenia, ponieważ oba są inicjowane w kontrolerach akcji)
  • Gdy PageCachemoduł jest włączony (prawdopodobnie zawsze w produkcji), pamiętaj, że jak tylko rozpocznie się generowanie układu, sesja klienta zostanie wyczyszczona \Magento\PageCache\Model\Layout\DepersonalizePlugin::afterGenerateXmlna wszystkich stronach, które można buforować. Oznacza to, że jeśli teraz sprawdzisz, czy klient jest zalogowany przez kontekst HTTP, nadal powie „tak”, ale dane klienta nie będą już dostępne w sesji klienta. Dlatego konieczne jest podwójne sprawdzenie przed próbą uzyskania dostępu do danych w sesji klienta. Może się to łatwo zdarzyć w bloku, chociaż jest mało prawdopodobne w kontrolerze akcji, ponieważ nie oczekuje się, że wygeneruje się tam układ ręcznie, zostanie wygenerowany, gdy kontroler akcji zwróci instancjęResultInterface

Aby wyeliminować ryzyko opisanych niespójności po włączeniu PageCache, rozważ użycie sesji klienta, jeśli jest ona już zainicjowana (dotyczy kontrolerów akcji). W przeciwnym razie użyj kontekstu HTTP.

Alex Paliarush
źródło
świetna wskazówka dla PageCache włączona, dzięki
LucScu
3
@Alex Używam poniżej kodu $ customerSession = $ objectManager-> get ('Magento \ Framework \ App \ Http \ Context'); $ isLoggedIn = $ customerSession-> getValue (\ Magento \ Customer \ Model \ Context :: CONTEXT_AUTH); Ale ze względu na pamięć podręczną włącz To pokazuje opcję Zaloguj się zamiast Wyloguj się do zalogowanego klienta. Jak mam to naprawić?
Nitesh
To nas ugryzło w tyłek, dziękuję. Twoja odpowiedź wymaga więcej uwagi :-) Włączenie pamięci podręcznej podczas produkcji utrudnia sesję. Umieść cachable = false w pliku XML trasy, jeśli piszesz niestandardowe wtyczki magento.
Ligemer,
2
dlaczego musisz ustawić 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);
Mage2.PRO
źródło
więc jak zdobyć klienta jest zalogowany @ Mage2.PRO?
xanka,
8
Nigdy nie powinieneś używać ObjectManager bezpośrednio
7ochem
Tak, zgodziłem się. Menedżer obiektów nie jest właściwą drogą. Wstrzyknąć CustomerFactory do konstruktora klasy.
CarComp
Powyższe rozwiązanie nie działa dla mnie
Ipsita Rout
@lpsita Daj mi znać, jeśli masz ten problem? Właśnie to naprawiłem :)
Jai
10

Żadne z tych rozwiązań nie działało dla mnie. Niektóre strony wydają się być zalogowane, a inne nie. Wygląda na to, że to błąd:

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

Skończyło się tworzenie pomocnika, który mógłbym wywołać w moich szablonach:

<?php
namespace MyVendor\MyModule\Helper;

use Magento\Framework\App\Helper\AbstractHelper;

/**
 * Created by Carl Owens ([email protected])
 * 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;
    }
}

Następnie mógłbym użyć pomocnika w moich szablonach w następujący sposób:

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

if ($helper->isLoggedIn()) {
    //show something
}
Carl Owens
źródło
To prawda, jedyny kod, który na mnie działał, jest twój. Dziękuję Ci!
George George
Jak mogę zadzwonić ->getCustomer()->getName()przy użyciu kontekstu, ponieważ jeśli korzystam z sesji, nie działa ona na wszystkich stronach.
George George,
jeśli włączona jest pamięć podręczna całej strony, jest to właściwa odpowiedź. Możesz najpierw sprawdzić sesję klienta, a jeśli to zwróci fałsz, możesz to zrobić
CompactCode
9

Aby zalogować się do użytkownika w szablonie, możesz po prostu zadzwonić do pomocnika w jednej linii:

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

<?php if( $_loggedin ) : ?>

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

<?php endif; ?>
Afham
źródło
Ładne rozwiązanie bez użycia menedżera obiektów.
Nitesh,
2
Nie działało to w wersji 2.1.5 z włączoną funkcją FPC i lakierem w trybie produkcyjnym.
thdoan 27.04.17
8

Żadne z rozwiązań tutaj nie działało dla mnie niezawodnie w Magento v2.1 z włączoną funkcją Full Page Cache i Varnish w trybie Production. W końcu znalazłem rozwiązanie, które działało w 100% z włączonym buforowaniem po otrzymaniu pomysłu vendor/magento/module-theme/view/frontend/templates/html/header.phtml. Oto moje rozwiązanie, które pokazuje link „Zaloguj się”, gdy użytkownik jest wylogowany, oraz link „Wyloguj się”, gdy użytkownik jest zalogowany:

<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>

AKTUALIZACJA: Od wersji 2.1.5 to rozwiązanie nie jest już niezawodne. Zobacz kwestię 9156 do rozwiązania.

thdoan
źródło
To dobre rozwiązanie. Chociaż możesz użyć cachable = "false" w pliku układu.
Dinesh Yadav
Mam cachable="false"w układzie XML dla tego bloku, ale lakier wciąż najwyraźniej buforuje go. Nie jestem pewien, czy to błąd, czy nie, ale Knockout to dobry sposób na obejście tego. Jedynym minusem jest to, że pojawia się niewielkie opóźnienie, zanim pojawi się link Zaloguj / Wyloguj z powodu powiązania KO.
thdoan 27.04.17
6

Istnieje wiele odpowiedzi na takie pytania ...

POBIERZ KLIENTA OBIEKTU ZAŁADUJ MODEL MODELU ZADAJ

Jest to NIEWŁAŚCIWA metodologia stosowana w Magento2.0. W wersji 2.0 można automatycznie wygenerować fabryki obiektów. Możesz wstrzyknąć je do swojego konstruktora w prawie każdej klasie i użyć ich. Przykład:

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
            }
CarComp
źródło
2
Jeśli pojawi się błąd w fabrykach, użyj pełnej ścieżki, np \Magento\Customer\Model\SessionFactory $sessionFactory.
thdoan 27.04.17
Poprawny. Zazwyczaj ogłaszam je na górze, żeby moje metody nie wyglądały jak wielki bałagan :)
CarComp
3

Witam mam odpowiedź tutaj:

$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
}

Źródło .

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

Zamienione get na tworzenie działa teraz dobrze:

$customerSession = $objectManager->create('Magento\Customer\Model\Session');
Manish
źródło
4
Nigdy nie należy używać ObjectManagerbezpośrednio
7ochem
Działa to tylko wtedy, gdy pamięć podręczna jest wyłączona, a nie w włączonej pamięci podręcznej.
Jai
@Jai, ta praca również dla mnie dotyczy rozwoju i produkcji. Czy możesz przesłać mi kroki, aby odtworzyć problem?
Manish,
Muszę sprawdzić, czy użytkownik jest zalogowany, czy nie. Ale poniższy kod działa tylko w wyłączonej pamięci podręcznej $ objectManager = \ Magento \ Framework \ App \ ObjectManager :: getInstance (); $ customerSession = $ objectManager-> create ('Magento \ Customer \ Model \ Session'); if ($ customerSession-> isLoggedIn ()) {// CODE}
Jai
Włącz buforowane: Działa tylko na niestandardowych stronach pulpitu, a nie na stronie głównej i na innych stronach witryny. Moje pytanie: magento.stackexchange.com/q/177964/29175
Jai
3

Jest to również jedno z rozwiązań „Sprawdź, czy klient jest zalogowany w Magento2”

Wypróbuj poniższy kod:

 $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()); 
 }
Soundararajan m
źródło
2

Wypróbuj poniższy kod:

<?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();
    }
}

Aby użyć powyższego kodu w pliku phtml, możesz wywołać funkcję isLoggedIn () jako:

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

Mam nadzieję, że dzięki tej pomocy.

Shubham Khandelwal
źródło
Cześć @Shubdham, to nie działa ..
Jafar Pinjar
to fajne rozwiązanie. dzięki
Zapytaj Bajtów
Tak, dzięki, mam nadzieję, że ci to pomoże.
Shubham Khandelwal
2

Mam najlepsze rozwiązanie. Opiera się na uwierzytelnieniu klienta . Część sesji z klientami nie działała, ale za każdym razem moje rozwiązanie będzie działać. Spójrzmy.

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

Dzięki.

Rafiqul Islam
źródło
1

Aktualne rozwiązanie pracujące (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;
    }
}
coresh
źródło
1

Jeśli chcesz sprawdzić, czy klient jest zalogowany, czy nie, użyj tego kodu w plikach 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   **/
}
Purvesh
źródło
2
Nigdy nie należy używać ObjectManagerbezpośrednio i nigdy nie należy używać tego typu kodu w szablonie. Powinieneś stworzyć funkcje w swojej klasie bloków, aby to zarządzać.
7ochem
Kiedy już wiesz, jak to zrobić poprawnie, zastanawiasz się, jak kiedykolwiek udało Ci się to zrobić w drugą stronę!
CarComp
0
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->get('Magento\Customer\Model\Session');

if($customerSession->isLoggedIn()) {

}
Divya
źródło
0

Inna odpowiedź:

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

Co myślisz?

xanka
źródło
0

Pobieranie statusu zalogowania z modelu sesji nie będzie działać, jeśli chcesz go użyć po włączeniu domyślnej pamięci podręcznej FPC Magento, w takim przypadku powinieneś użyć SessionFactory.

Sesja nie jest inicjowana, jeśli buforowanie FPC jest włączone, szczegóły: https://github.com/magento/magento2/issues/3294#issuecomment-328464943

Aby rozwiązać ten problem, musisz SessionFactoryna przykład:

/**
* @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();
}
Wolfack
źródło
-1

Próbowałem wielu sposobów znalezionych w Google, ale żadne z tych rozwiązań nie działa. SO Sprawdziłem więc podstawową funkcjonalność i utworzyłem plik php, aby sprawdzić, czy klient jest zalogowany czy nie bez korzystania z Object Managera.


            / **
         * Sesja klienta
         * Moduł stworzony przez Web Technology Codes
         * Opracowany przez Vinay Sikarwar
         * @var \ Magento \ Framework \ App \ Http \ Context
         * /
        chroniona sesja $;

        / **
         * Konstruktor rejestracji.
         * Kontekst @param $ kontekst
         * @param array $ data
         * /
        funkcja publiczna __construct (
            Kontekst $ kontekst,
                    \ Magento \ Framework \ Session \ Generic $ session,
            tablica $ data
        )
        {
                    $ this -> _ session = $ session;
                    rodzic :: __ konstrukcja ($ kontekst, $ dane);
        }

            / **
         * Sprawdzanie statusu logowania klienta
         *
         * @api
         * @return bool
         * /
        funkcja publiczna isCustomerLoggedIn ()
        {
            return (bool) $ this-> getCustomerId ()
                && $ this-> checkCustomerId ($ this-> getId ())
                &&! $ this-> getIsCustomerEmulated ();
        }
    }

Aby uzyskać więcej informacji, sprawdź tutaj http://blog.webtechnologycodes.com/customer-loggedin-check-magento2

Vinay Sikarwar
źródło