1

I'm trying to send a form from a Java Spring Application to Magento.

What I'm doing in Java is just creating an standard form and on action I wrote Magento's controller path.

Like this:

http://ip/application/send/application

When I post the form, I get redirected to just http://ip

and a message showing : Invalid Form Key. Please refresh the page.

This is my controller on Magento:

public function execute()   
    {   $post = $this->getRequest()->getPostValue();
        $resultPage = $this->_resultPageFactory->create();   
        $block = $resultPage->getLayout()->getBlock('application_send');
        $block->setData('post',$post);
        return $resultPage;   
    } 

And my layout.xml for the controller:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body> 
        <referenceContainer name="content">
            <block class="Vendor\Application\Block\Main" name="application_send" template="Vendor_Application::application.phtml"/>
        </referenceContainer>    
    </body>
</page>

Do I need to return a token on controller? or do I need to send a token from Java Form?

Greetings!

Oscar Vazquez
  • 553
  • 7
  • 37

1 Answers1

0

Each form on magento must send additional param named FROM_KEY to prevent cross site request: https://magento.stackexchange.com/a/131190/37497

For your purpose it's would be better to create a public api method. If you want to ignore that you should rewrite default magento controller code there:

vendor/magento/framework/App/FrontController.php

in the processRequest code:

//Validating a request only once.
    if (!$this->validatedRequest) {
        try {
            $this->requestValidator->validate(
                $request,
                $actionInstance
            );
        } catch (InvalidRequestException $exception) {
            //Validation failed - processing validation results.
            $this->logger->debug(
                'Request validation failed for action "'
                . get_class($actionInstance) . '"',
                ["exception" => $exception]
            );
            $result = $exception->getReplaceResult();
            $area = $this->areaList->getArea($this->appState->getAreaCode());
            $area->load(Area::PART_DESIGN);
            $area->load(Area::PART_TRANSLATE);
            if ($messages = $exception->getMessages()) {
                foreach ($messages as $message) {
                    $this->messages->addErrorMessage($message);
                }
            }
        }
        $this->validatedRequest = true;
    }

where the $this->requestValidator contains Magento\Framework\App\Request\CsrfValidator which is checking the form key for post request of the fromtend and adminhtml areas:

private function validateRequest(
    HttpRequest $request,
    ActionInterface $action
): bool {
    $valid = null;
    if ($action instanceof CsrfAwareActionInterface) {
        $valid = $action->validateForCsrf($request);
    }
    if ($valid === null) {
        $valid = !$request->isPost()
            || $request->isXmlHttpRequest()
            || $this->formKeyValidator->validate($request);
    }
return $valid;

}

If your action (controller) does not implement the CsrfAwareActionInterface it would be better to implement it and rewrite the public function validateForCsrf(RequestInterface $request): ?bool inside your action, just like:

public function validateForCsrf(RequestInterface $request): ?bool
{
    return true;
}
Siarhey Uchukhlebau
  • 15,957
  • 11
  • 54
  • 83
  • Yeah I have an API Endpoint, but as far as I know, I can't show a "view" from an endpoint, or is there a way to redirect to a controller? – Oscar Vazquez May 13 '21 at 16:42
  • @OscarVazquez I meant you can save a data using API and then redirect customer from thirdparty app to magento controller using GET. The FROM_KEY required only for the POST request in Magento. Anyway the simplest way is implement the Magento\Framework\App\CsrfAwareActionInterface in your controller. – Siarhey Uchukhlebau May 13 '21 at 16:44