Magento 2 How to Add Alternative HTTP headers

From Brian Nelson Ramblings
Jump to: navigation, search

Magento 2 How to Add Alternative HTTP headers

If you have more than one frontend server running on your Magento 2 store, it’s needed to load balance the traffic between the nodes. In this case we have a new instance between the browser and the web-server.

Often it’s a system like HAProxy or Varnish.

If the load balancer or proxy receives a request from a browser, it forwards it to backend server in the internal network.

The IP address of the client is than added to a forward header which contains the IP address of a forward chain.

Example:

X-Forwarded-For: client, proxy1, proxy2

In some situation i.e. for GEO-IP checks, you need the real IP address of a client.

If you don’t configure Magento the remote address is always the proxy or load balancer (127.0.0.1).

That’s not what we want. We need the first part of the comma separated list of the IP chain.

Magento offers us a mechanism to solve this issue.

Remote Address

The key to solve the issue is the class

Magento\Framework\HTTP\PhpEnvironment\RemoteAddress 

which is provided by the Magento 2 framework.

In Magento 2 it’s prohibited to call the $_SERVER['REMOTE_ADD'] directly.

The RemoteAddress class is a wrapper to deal with the remote address.

The correct way to get the remote address is this: use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;

use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
  
class MyClass
{
    /**
     * @var RemoteAddress
     */
    private $remoteAddress;
 
    public function __construct(RemoteAddress $remoteAddress)
    {
        $this->remoteAddress = $remoteAddress;
    }
 
    public function doSomething()
    {
        $ipAddressOfTheClient = $this->remoteAddress->getRemoteAddress();
    }
}

Configuration

It’s possible to inject a list of alternative headers to the RemoteAddress class by Dependency Injection.

This config isn’t related to any module. It’s a special config for a production server setup.

It’s important to know that Magento 2 will load any di.xml file from any subfolder of the app/etc folder!

With this information we can create a subfolder like app/etc/myproject/di.xml with the following content:

<?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\HTTP\PhpEnvironment\RemoteAddress">
         <arguments>
             <argument name="alternativeHeaders" xsi:type="array">
                 <item name="x-forwarded-for" xsi:type="string">HTTP_X_FORWARDED_FOR</item>
             </argument>
         </arguments>
     </type>
 </config>

After that Magento will look into the given HTTP header „X-Forwarded-For“. The name of the header is normalized by PHP.

X-Forwarded-For is available as $_SERVER['HTTP_XFORWARDED_FOR'].

It’s possible to add more than one header to alternative header list.