Magento 2 – AJAX Request in Backend Template Redirecting to Login Page

ajaxbackendmagento2redirect

I am working with Magento2.

I've created some backend controllers, which are accessible in backend.

In my backend template file, I want to call the controller function with jQuery like this:

require( [ 'jquery', 'js/Services' ], function ( $, Services )
{
    $( document ).on( 'change', '.entry-edit #sku', function ()
    {
        Services.getProductName( $( "#sku" ).val());
    } );...

The implementation of the service method is like this:

    Services.getProductName = function (sku)
{
    var request = $.ajax( {
        url: "/admin123/backend/Product/showName?sku=" + sku,
        type: 'GET'
    } );

    request.done( function ( result )
    {
        $( "#name" ).val( result );
    } );

    request.fail( function ( error )
    {
        console.dir(error);
        $( "#name" ).val( "Produkt nicht gefunden" );
    } );

};

My backend controller:

class ShowName extends \Magento\Backend\App\Action
{
    const ADMIN_RESOURCE = 'Ruck_Restclient::showName';

/**
 * {@inheritdoc}
 */
protected function _isAllowed()
{
    return true;//$this->_authorization->isAllowed(self::ADMIN_RESOURCE);
}

/**
 * @return void
 */
public function execute()
{
    try
    {
        $sku = $this->getRequest()->getParam( 'sku' );
        $helper = new Data();
        $productName = $helper->getKundenArtikelNumberByProductNumber( $sku );
        $this->getResponse()->setBody( $productName );
    }
    catch ( Exception $ex )
    {
        $this->getResponse()->setBody( $ex->getMessage() );
    }
}

}

I'm not able to to proceed the getProductname() function. After the call is fired in adminhtml/product/edit/tabs, I'm getting immediatly redirected to backend login page.

After my research, I figured out, that the dispatch method from \Magento\Backend\App\Action checks the login status and redirects to login page if status is not logged in.

My expectation is, that if I fire an request from an admintemplate (adminhtml/product/edit/tabs) which is inside backend scope, I could consume the controller action.

Do I need to add some additional login headers or is my proceed basically wrong?

Best Answer

Magento is using secure key validation in admin aria.

Simplest way to use secure key is use POST and add form_key to data. Example:

jQuery.ajax( {
    url: 'http://mage.dev/admin/vendor/module/validateTest',
    data: {form_key: window.FORM_KEY},
    type: 'POST'
}).done(function(a) { 
    console.log(a); // log: {a: "b"}
});

And my controller looks like

<?php
namespace Vendor\Module\Controller\Adminhtml\Entity;

use Magento\Backend\App\Action;

/**
 * Entity validate
 */
class ValidateTest extends \Magento\Backend\App\Action
{
    /**
     * @var \Magento\Framework\Controller\Result\JsonFactory
     */
    protected $resultJsonFactory;

    /**
     * ValidateTest constructor.
     * @param Action\Context $context
     * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
    ) {
        parent::__construct($context);
        $this->resultJsonFactory = $resultJsonFactory;
    }

    /**
     * Validate product
     *
     * @return \Magento\Framework\Controller\Result\Json
     */
    public function execute()
    {
        return $this->resultJsonFactory->create()->setData([
            'a' => 'b'
        ]);
    }


   /**
     * Check for is allowed
     *
     * @return boolean
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('Vendor_Module::resource');
    }
}