SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH SPECIAL OFFER: ENJOY 3 MONTHS OF SHOPIFY FOR $1/MONTH
get customer session data
get customer session data

How to get customer session data when using varnish cache in Magento 2

You can’t get customer session data when using varnish cache in Magento 2.

Because as soon as layout generation started, the customer session will be cleared by \Magento\PageCache\Model\Layout\DepersonalizePlugin::afterGenerateXml on all cacheable pages. So we can’t get any customer session data from \Magento\Customer\Model\Session.

But you can use \Magento\Framework\App\Http\Context instead if you don’t need more than customer_group and customer_not_logged_in values.

Using HttpContext

protected $httpContext;

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Framework\App\Http\Context $httpContext,
    array $data = []
) {
    $this->httpContext = $httpContext;
    parent::__construct($context, $data);
}

public function getCustomerIsLoggedIn()
{
    return (bool)$this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
}
in case

In case you need other customer attributes like Customer id, Name, Email… you will need to follow these steps to create a plugin to set customer session data into httpContext before being cleared

1. Define plugin a di.xml file
2. Create a plugin 
3. Use httpContext data in block

1. Define plugin a di.xml file

Create a di.xml in the Vendor\Module\etc\frontend directory.

<?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\Framework\App\Action\AbstractAction">
    	<plugin name="customer-session-data-to-context" type="Vendor\Module\Plugin\CustomerSessionContext"/>
    </type>
</config>

2. Create a plugin 

Create Vendor\Module\Plugin\CustomerSessionContext.php

<?php
namespace Vendor\Module\Plugin;

class CustomerSessionContext
{
    /**
 	* @var \Magento\Customer\Model\Session
 	*/
    protected $customerSession;

    /**
 	* @var \Magento\Framework\App\Http\Context
 	*/
    protected $httpContext;

    /**
 	* @param \Magento\Customer\Model\Session $customerSession
 	* @param \Magento\Framework\App\Http\Context $httpContext
 	*/
    public function __construct(
    	\Magento\Customer\Model\Session $customerSession,
    	\Magento\Framework\App\Http\Context $httpContext
    ) {
    	$this->customerSession = $customerSession;
    	$this->httpContext = $httpContext;
    }

    /**
 	* @param \Magento\Framework\App\ActionInterface $subject
 	* @param callable $proceed
 	* @param \Magento\Framework\App\RequestInterface $request
 	* @return mixed
 	*/
    public function aroundDispatch(
    	\Magento\Framework\App\ActionInterface $subject,
    	\Closure $proceed,
    	\Magento\Framework\App\RequestInterface $request
    ) {
    	$this->httpContext->setValue(
        	'customer_id',
        	$this->customerSession->getCustomerId(),
        	false
    	);

    	$this->httpContext->setValue(
        	'customer_name',
        	$this->customerSession->getCustomer()->getName(),
        	false
    	);

    	$this->httpContext->setValue(
        	'customer_email',
        	$this->customerSession->getCustomer()->getEmail(),
        	false
    	);

    	return $proceed($request);
    }
}

Now we can get data like customer_id, customer_name and customer_email from customer session and set it in httpContext using the plugin.

You can set whatever data that customer session have and get it later in block.

3. Use httpContext data in block

Initialize \Magento\Framework\App\Http\Context in your custom block file.

<?php

namespace Vendor\Module\Block;

class CustomBlock extends \Magento\Framework\View\Element\Template
{
    protected $httpContext;

    public function __construct(
    	\Magento\Framework\View\Element\Template\Context $context,
    	\Magento\Framework\App\Http\Context $httpContext,
    	array $data = []
    ) {
    	$this->httpContext = $httpContext;
    	parent::__construct($context, $data);
    }

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

    public function getCustomerId()
    {
    	return $this->httpContext->getValue('customer_id');
    }

    public function getCustomerName()
    {
    	return $this->httpContext->getValue('customer_name');
    }

    public function getCustomerEmail()
    {
    	return $this->httpContext->getValue('customer_email');
    }

}

Now you can get customer id, name and email from the block and can be used in the frontend even when using varnish cache.