set x-frame-options in custom controller magento2
-
14-04-2021 - |
Question
I have a custom controller with below code.
namespace Vendor\Module\Controller\Service;
class Login extends \Magento\Framework\App\Action\Action{
protected $_storeManager;
protected $_customerFactory;
protected $_customerSession;
protected $_addressRepository;
protected $_addressDataFactory;
protected $addressFactory;
protected $customerRepository;
protected $checkoutSession;
private $logger;
protected $cart;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Customer\Model\CustomerFactory $customerFactory,
\Magento\Customer\Model\Session $customerSession,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Checkout\Model\Cart $cart,
\Magento\Customer\Api\AddressRepositoryInterface $addressRepository,
\Magento\Customer\Api\Data\AddressInterface $addressDataFactory,
\Magento\Customer\Model\AddressFactory $addressFactory,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
\Psr\Log\LoggerInterface $logger
) {
$this->_storeManager = $storeManager;
$this->_customerFactory = $customerFactory;
$this->cart = $cart;
$this->_customerSession = $customerSession;
$this->_addressRepository = $addressRepository;
$this->_addressDataFactory = $addressDataFactory;
$this->_addressFactory = $addressFactory;
$this->checkoutSession = $checkoutSession;
$this->customerRepository = $customerRepository;
$this->logger = $logger;
parent::__construct($context);
}
public function execute() {
$customerPin = $this->getRequest()->getParam('pin');
echo $customerPin;die;
}
Above code reads the parameter pin from the url and display the parameter value.
http://www.example.com/test/service/login/pin/6
This works only if accessed in the same website. Suppose the controller is accessed like iframe, from the other domain. its showing blank screen.
is there any setting to be done? from research i found we need to set X-Frame-Options to make it work.
if so how that can be set from controller?
Can anyone look into this and update me the solution please.
Solution
I tried a few different versions of setHeader() but the only thing that worked for me was overwriting XFrameOptions.
- Vendor/Module/etc/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">
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<!-- Preference type used, as we can't use a plugin on a __construct function -->
<preference for="\Magento\Framework\App\Response\HeaderProvider\XFrameOptions" type="Vendor\Module\ResponseHeader\XFrameOptions" />
</config>
- Vendor/Module/ResponseHeader/XFrameOptions.php
<?php
namespace Vendor\Module\ResponseHeader;
class XFrameOptions extends \Magento\Framework\App\Response\HeaderProvider\XFrameOptions {
public function __construct(
$xFrameOpt = 'SAMEORIGIN',
\Magento\Framework\App\Request\Http $request
) {
// Eg if your iframe controller frontname is 'test'
$isIframeController =
($request->getModuleName() == 'test');
// Skip this for the iFrame page
if ($isIframeController) {
return;
}
return parent::__construct($xFrameOpt);
}
}
This doesn't set the X-Frame-Header for the custom controller (eg "test"), but sets it for all other pages, so that your site is still protected against iFrame attacks.
OTHER TIPS
Assuming you have defined your webapi endpoint like this:
http://www.example.com/test/service/login/pin
Then you can get the Post Value like this:
http://www.example.com/test/service/login/pin?pin=6
Otherwise, you will get a blank response when an endpoint is called inside an iframe
.
I think you are trying to include a local environment into a iframe but that is not possible. The outside world can not access http://localsite/test/service/login/pin/6