16

Which class I should override in order to redirect a customer to a specific page after login?

I have tried to set Redirect Customer to Account Dashboard after Logging in in the store configuration but it is not working.

10
  • You enable or disable Guest Checkout? Sep 5 '16 at 15:53
  • I have disabled guest checkout.
    – TFS
    Sep 5 '16 at 15:54
  • How about your current issue? Sep 10 '16 at 7:32
  • The code you provided is a bit different from my magento. Maybe it from different versions. And I don't understand why it is related to cookie. I finally resolved it by overriding the LoginPost class. I posted my answer below. Thanks!
    – TFS
    Sep 11 '16 at 4:34
  • 1
    My magento version is v2.0.8
    – TFS
    Sep 11 '16 at 4:37
38

A plugin is a better solution in this case because your extended class might need to be updated when Magento 2 updates.

Here is a solution using a after-plugin on LoginPost->execute() as suggested by Xenocide8998.

/Vendor/Module/etc/frontend/di.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
  <type name="\Magento\Customer\Controller\Account\LoginPost">
    <plugin name="vendor_module_loginpostplugin" type="\Vendor\Module\Plugin\LoginPostPlugin" sortOrder="1" />
  </type>
</config>

/Vendor/Module/Plugin/LoginPostPlugin.php:

<?php

/**
 *
 */
namespace Vendor\Module\Plugin;

/**
 *
 */
class LoginPostPlugin
{

    /**
     * Change redirect after login to home instead of dashboard.
     *
     * @param \Magento\Customer\Controller\Account\LoginPost $subject
     * @param \Magento\Framework\Controller\Result\Redirect $result
     */
    public function afterExecute(
        \Magento\Customer\Controller\Account\LoginPost $subject,
        $result)
    {
        $result->setPath('/'); // Change this to what you want
        return $result;
    }

}
6
  • 3
    It's work well. One thing is when you need to $result->setPath('/'); to your custom path don't use "/" before URL, for example. $result->setPath('customer/dashboard/'); Dec 17 '18 at 8:50
  • Good approach using plugin Jun 20 '19 at 10:20
  • Perfect Work thank you
    – HaFiz Umer
    Jul 2 '19 at 10:16
  • 1
    Your only issue with this is if the customer tries to login and fails, then you're still going to hit the home page. There isn't any way to catch failed logins.
    – andy jones
    Oct 17 '19 at 13:31
  • how can I pass current page url to this plugin?
    – Rahul
    Nov 5 '19 at 13:37
7

I resolved it by overriding the LoginPost class

etc/di.xml

<preference for="Magento\Customer\Controller\Account\LoginPost" type="Vendor\Module\Controller\Account\LoginPost" />

Vendor/Module/Controller/Account/LoginPost.php

<?php

namespace Vendor\Module\Controller\Account;

use Magento\Customer\Model\Account\Redirect as AccountRedirect;
use Magento\Framework\App\Action\Context;
use Magento\Customer\Model\Session;
use Magento\Customer\Api\AccountManagementInterface;
use Magento\Customer\Model\Url as CustomerUrl;
use Magento\Framework\Exception\EmailNotConfirmedException;
use Magento\Framework\Exception\AuthenticationException;
use Magento\Framework\Data\Form\FormKey\Validator;

/**
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class LoginPost extends \Magento\Customer\Controller\Account\LoginPost {

    public function execute() {
        if ($this->session->isLoggedIn() || !$this->formKeyValidator->validate($this->getRequest())) {
            /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
            $resultRedirect = $this->resultRedirectFactory->create();
            $resultRedirect->setPath('home');
            return $resultRedirect;
        }

        if ($this->getRequest()->isPost()) {
            $login = $this->getRequest()->getPost('login');
            if (!empty($login['username']) && !empty($login['password'])) {
                try {
                    $customer = $this->customerAccountManagement->authenticate($login['username'], $login['password']);
                    $this->session->setCustomerDataAsLoggedIn($customer);
                    $this->session->regenerateId();
                } catch (EmailNotConfirmedException $e) {
                    $value = $this->customerUrl->getEmailConfirmationUrl($login['username']);
                    $message = __(
                            'This account is not confirmed.' .
                            ' <a href="%1">Click here</a> to resend confirmation email.', $value
                    );
                    $this->messageManager->addError($message);
                    $this->session->setUsername($login['username']);
                } catch (AuthenticationException $e) {
                    $message = __('Invalid login or password.');
                    $this->messageManager->addError($message);
                    $this->session->setUsername($login['username']);
                } catch (\Exception $e) {
                    $this->messageManager->addError(__('Invalid login or password.'));
                }
            } else {
                $this->messageManager->addError(__('A login and a password are required.'));
            }
        }

        $resultRedirect = $this->resultRedirectFactory->create();
        $resultRedirect->setPath('home');
        return $resultRedirect;
    }

}
5
  • 16
    I think using a plugin with the afterExecute() would be a cleaner option Nov 4 '16 at 4:31
  • 4
    This not a good approach and will only cause problems in the future. Plugin is the way to go.
    – phagento
    Dec 13 '18 at 9:05
  • can we redirect from account dashboard to sales order history page by default? Sep 5 '19 at 6:16
  • 1
    yeah,plugin is right option but using this if the customer tries to login and fails, then you're still going to hit the home page. Aug 25 '20 at 5:24
  • 1
    Above preference code is not working....... Sep 21 '20 at 10:27
2

The simplest solution that i found

If the custom URL is sales/order/history

Vendor/Extension/etc/frontend/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="\Magento\Customer\Controller\Account\LoginPost">
        <plugin name="redirect_custom_url" type="\Vendor\Extension\Plugin\RedirectCustomUrl" sortOrder="1"/>
    </type>
</config>

Vendor/Extension/Plugin/RedirectCustomUrl.php

<?php
namespace Vendor\Extension\Plugin;
class RedirectCustomUrl
{
    public function afterExecute(
        \Magento\Customer\Controller\Account\LoginPost $subject,
        $result)
    {
        $customUrl = 'sales/order/history';
        $result->setPath($customUrl);
        return $result;
    }
}

Vote this answer up if it helps.

0

That the current local storage caused our issue.
If we enable or disable Redirect Customer to Account Dashboard after Logging in and Guest Checkout in Configuration, this feature will work well. However, we need to clear your local storage.

We can check the local storage localStorage.getItem('mage-cache-storage').

Take a look:

vendor/magento/module-checkout/view/frontend/web/js/sidebar.js

var cart = customerData.get('cart'),
customer = customerData.get('customer');
if (!customer().firstname && cart().isGuestCheckoutAllowed === false) {
    // set URL for redirect on successful login/registration. It's postprocessed on backend.
    $.cookie('login_redirect', this.options.url.checkout);
    if (this.options.url.isRedirectRequired) {
        location.href = this.options.url.loginUrl;
    } else {
        authenticationPopup.showModal();
    }

    return false;
}

Magento will set the cookie $.cookie('login_redirect', this.options.url.checkout) based on customerData from local storage.

From the controller vendor/magento/module-customer/Controller/Account/LoginPost.php. It will check the redirect URL from the cookie.

$redirectUrl = $this->accountRedirect->getRedirectCookie();
if (!$this->getScopeConfig()->getValue('customer/startup/redirect_dashboard') && $redirectUrl) {
    ......
    return $resultRedirect;
}

Magento version:

-Magento version 2.1.0

0

I resolved this by passing referer in custom module controller.

Step1 `

use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Customer\Model\Session;
use Magento\Framework\UrlInterface;

class Approve extends \Magento\Framework\App\Action\Action {

    /** 
    * @var \Magento\Framework\View\Result\Page 
    */
    protected $resultPageFactory;

    /** 
    * $param \Magento\Framework\App\Action\Context $context */

    /**
    * @param CustomerSession
    */

    protected $_customerSession;

    protected $_urlInterface;

    public function __construct(
        Context $context,
        PageFactory $resultPageFactory,
        Session $customerSession,
        UrlInterface $urlInterface
    )
    {
        $this->resultPageFactory = $resultPageFactory;
        $this->_customerSession  = $customerSession;
        $this->_urlInterface     = $urlInterface;
        parent::__construct($context);

    }

    public function execute(){
        $url  = $this->_urlInterface->getUrl('*/*/*', ['_current' => true, '_use_rewrite' => true]); 
// here pass custom url or you can either use current url on which you are currently and want to come back after logged in.

        $loginUrl = $this->_urlInterface->getUrl('customer/account/login', array('referer' => base64_encode($url)));
        if($this->_customerSession->isLoggedIn()){
            return $this->resultPageFactory->create();
        }
        $this->_redirect($loginUrl);
    }
}`

Step2

Go to Admin : Store > Configuration > Customers > Customer Configuration > Login Options > Redirect Customer to Account Dashboard after Logging in > No

0

I've created a module that allows me to specify the redirectUrl via querystring when redirecting customers to /customer/account/login.

For example /customer/account/login?redirectUrl=https://someurl.com or ?redirectUrl=some/path.

I did this by creating 2 plugins:

1. Plugin for Magento\Customer\Controller\Account\Login

Just to capture the parameter redirectUrl and save it to the customer session.

use Magento\Customer\Model\Session;
use Magento\Framework\App\Request\Http;

class CustomerLoginPlugin
{
    private Session $session;
    private Http $httpRequest;

    public function __construct(Session $session, Http $httpRequest)
    {
        $this->session = $session;
        $this->httpRequest = $httpRequest;
    }

    /**
     * @param \Magento\Customer\Controller\Account\Login $subject
     * @param                                            $result
     */
    public function afterExecute(\Magento\Customer\Controller\Account\Login $subject, $result)
    {
        if ($redirectUrl = $this->httpRequest->getParam('redirectUrl', false)) {
            $this->session->setRedirectUrl($redirectUrl);
        }
        
        return $result;
    }
}

2. Plugin for Magento\Customer\Controller\Account\LoginPost

This will change the response in case the response is a redirect. So, if we have no errors in the loginPost response, I change the redirect url.


use Magento\Customer\Controller\Account\LoginPost;
use Magento\Customer\Model\Session;

class CustomerLoginPostPlugin
{
    private Session $session;

    public function __construct(Session $session)
    {
        $this->session = $session;
    }

    /**
     * @param \Magento\Customer\Controller\Account\LoginPost $subject
     * @param                                                $result
     */
    public function afterExecute(\Magento\Customer\Controller\Account\LoginPost $subject, $result)
    {
        if ($result instanceof \Magento\Framework\Controller\Result\Redirect && $this->session->getRedirectUrl()) {
            $result->setPath($this->session->getRedirectUrl());
        }
        
        return $result;
    }
}

Example of use

if (!$this->customerSession->isLoggedIn()) {
    $resultRedirect = $this->redirectFactory->create();
    $resultRedirect->setPath('customer/account/login', ['redirectUrl'=>'some/pathOrUrl']);
    return $resultRedirect;
}

Note that if you want to always redirect to some specific url, you can ignore the first Plugin, and just replace the setPath parameter to whatever you want (answering the original question).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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