10

I need to redirect user to a landing page if not logged in. I find a similar work in this link. Is there a solution for Magento 2?

3 Answers 3

21

If we want to catch controller_action_predispatch, we can follow:

app/code/Vendor/Module/etc/events.xml


     <event name="controller_action_predispatch">
            <observer name="check_login_persistent" instance="Vendor\Module\Observer\CheckLoginPersistentObserver" />
     </event>

app/code/Vendor/Module/Observer/CheckLoginPersistentObserver.php

namespace Vendor\Module\Observer;
use Magento\Framework\Event\ObserverInterface;


class CheckLoginPersistentObserver implements ObserverInterface
{
         /**
         * @var \Magento\Framework\App\Response\RedirectInterface
         */
        protected $redirect;

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

        public function __construct(
            \Magento\Customer\Model\Session $customerSession,
            \Magento\Framework\App\Response\RedirectInterface $redirect

        ) {

            $this->_customerSession = $customerSession;
            $this->redirect = $redirect;

        }

        public function execute(\Magento\Framework\Event\Observer $observer)
        {
            $actionName = $observer->getEvent()->getRequest()->getFullActionName();
            $controller = $observer->getControllerAction();

            $openActions = array(
                'create',
                'createpost',
                'login',
                'loginpost',
                'logoutsuccess',
                'forgotpassword',
                'forgotpasswordpost',
                'resetpassword',
                'resetpasswordpost',
                'confirm',
                'confirmation'
            );
            if ($controller == 'account' && in_array($actionName, $openActions)) {
                return $this; //if in allowed actions do nothing.
            }
            if(!$this->_customerSession->isLoggedIn()) {
                $this->redirect->redirect($controller->getResponse(), 'customer/account/login');
            }

        }

}
2
  • 2
    if ($controller == 'account' && in_array($action, $openActions)) { return $this; //if in allowed actions do nothing. } this code never executed their is no variable with name action in the code. also in __construct( you placed a "," at end which leads to an error. Aug 17, 2016 at 11:21
  • 2
    How do you reference your specific controller for this? I Have copied the code but don't quite understand how to fire it when my controller is hit.
    – harri
    Sep 28, 2017 at 11:45
7

For more optimize and working code you can follow the below steps.

  1. create event file @ app\code\Vendor\Module\etc\frontend\events.xml

    <?xml version='1.0'?>
    <config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd'>
        <event name='controller_action_predispatch'>
            <observer
                    name='checklogin'
                    instance='Vendor\Module\Model\Observer'
            />
        </event>
    </config>
    
    
  2. Create Observer file app\code\Vendor\Module\Model\Observer.php

    namespace Vendor\Module\Model;
    
    class Observer implements \Magento\Framework\Event\ObserverInterface
    {
    
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        # check if user is logged in
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $customerSession = $objectManager->get('Magento\Customer\Model\Session');
        if(!$customerSession->isLoggedIn())
        {
            $request = $objectManager->get('Magento\Framework\App\Request\Http');
            //get instance for URL interface
            /** @var \Magento\Framework\UrlInterface $urlInterface */
            $urlInterface = $objectManager->get('Magento\Framework\UrlInterface');
            // URL to redirect to
            $url = $urlInterface->getUrl('customer/account/login');
            if(strpos($request->getPathInfo(), '/customer/account/') !== 0)
            {
                # redirect to /customer/account/login
                $observer->getControllerAction()
                    ->getResponse()
                    ->setRedirect($url);
            }
        }
    }
    
2
  • Added this to my custom module, does not work for me, magento2.4. Also missing closing bracket on codeblock #2
    – 00-BBB
    Mar 15, 2021 at 16:48
  • Observer redirect is working . Apr 28, 2021 at 7:56
5

There is a much easier solution. Look at this file:

src/vendor/magento/module-sales/etc/di.xml

<type name="Magento\Sales\Controller\Order\History">
    <plugin name="authentication" type="Magento\Sales\Controller\Order\Plugin\Authentication"/>
</type>

So you just need to use the authentication plugin in your module di.xml

2
  • Much easier! Seems like the proper Magento way also.
    – harri
    Feb 25, 2021 at 11:14
  • can the <type> be ommitted / changed? Or does it not matter it says 'Order\History' ?
    – 00-BBB
    Mar 15, 2021 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.