This guide explains how to secure Magento 2 API with clear examples. You will learn token generation, authentication types, and permission control.
We will generate tokens to access Magento 2 API. Magento 2 provides three types of API Authentication.
- Token-Based authentication
- OAUTH-Based authentication
- Session-Based Authentication
Also, Magento 2 Security extension helps secure your website from various attacks and hacks.
1) Secure Magento 2 API using Token-based authentication
To make a web API call from a client such as a Magento 2 mobile application, you must supply an access token.
Request for Token
Magento 2 offers separate token services for administrators and customers. When you request a token from one of these services, it returns a unique access token in exchange for the account’s username and password, enabling secure authentication for API calls.
Request for Customer Token
Customer token : /V1/integration/customer/token

Request for Admin Token
Admin Token : /V1/integration/admin/token

Authentication
Magento 2 lets developers define web API resources and assign their permissions directly in the webapi.xml configuration file.
Before making web API calls, you must authenticate your identity and ensure you have the necessary permissions to access the API resource. Authentication lets the application determine the caller’s user type. A user’s role—whether administrator, integration, customer, or guest—directly determines which resources the API call can access.
| USER TYPE | ACCESSIBLE RESOURCES (DEFINED IN WEBAPI.XML) |
| Administrator or Integration | if administrators are authorized for the Magento_Customer::group resource, they can make a GET /V1/customerGroups/:id call. |
| Customer | Resources with anonymous or self permission |
| Guest user | Resources with anonymous permission |
Example for self
The user authenticates with their username and password. In response, the system generates a token, which serves as self-permission for all subsequent actions and API requests.
<route url="/V1/customers" method="GET">
<service class="Vendor\Module\Api\CustomerManagementInterface" method="getCustomerList"/>
<resources>
<resource ref="self"/>
</resources>
<data>
<parameter name="customer_id" force="true">%customer_id%</parameter>
</data>
</route>
Example for anonymous
Unauthenticated users can access these Web APIs.
<route url="/V1/products" method="GET">
<service class="Venodor\Module\Api\ProductRepositoryInterface" method="getProducts"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
Example for admin-authorized REST API
Custom web API in Magento 2
<route url="/V1/products" method="GET">
<service class="Venodor\Module\Api\ProductRepositoryInterface" method="getProducts"/>
<resources>
<resource ref="Vendor_Module::name"/>
</resources>
</route>
Create a custom module ACL in etc/acl.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
<acl>
<resources>
<resource id="Magento_Backend::admin">
<resource id="Vendor_Module::name" title="Pruduct List"/>
</resource>
</resources>
</acl>
</config>
2). Secure Magento 2 API via OAuth-based authentication
Adobe Commerce and Magento Open Source use OAuth 1.0a for secure API authentication. OAuth works as a token-passing mechanism, allowing the system to control which third-party applications can access internal data without exposing or storing user IDs or passwords.
In Commerce, a third-party application that authenticates via OAuth is called an integration. Each integration specifies the resources the application can access, either granting access to all resources or a selected subset.
During integration registration, Commerce generates the tokens the application needs for authentication. First, it creates a request token, which is short-lived and must be exchanged for an access token. Access tokens last for a long period and remain valid until the merchant explicitly revokes the application’s access.
OAuth authentication process to secure magento 2 API
The following diagram shows the OAuth authentication process. Each step is described further.

- Create an integration: The merchant creates a new integration from the Admin panel. Commerce generates a consumer key and a consumer secret for the integration.
- Activate the integration: The OAuth process starts when the merchant activates the integration. Magento sends the consumer key, consumer secret, OAuth verifier, and the store URL to the external application using an HTTPS POST to the callback URL defined in Admin.
- Process activation information: The integrator stores the activation information received in step 2. These parameters are required for requesting tokens later in the flow.
- Call the application’s login page: Commerce invokes the page defined in the Identity Link field in Admin to initiate the login process on the external application.
- Merchant logs in to the external application: The merchant enters credentials on the login page. Upon successful login, the application redirects back to the location specified in the call, and the login page is dismissed.
- Request a request token: The external application calls the POST /oauth/token/request REST API to request a request token. The Authorization header includes the consumer key and other required parameters.
- Send the request token: Commerce responds with the request token and request token secret.
- Request an access token: The application calls the POST /oauth/token/access REST API to exchange the request token for an access token. The Authorization header includes the request token and other required information.
- Commerce sends the access token: If the request succeeds, Magento returns the access token and access token secret.
- Access Magento resources: The application can now make authenticated API calls. Every request to Commerce must include the full set of parameters in the Authorization header to access the web APIs.
Activate an integration to secure Magento 2 API
You must configure the integration from the Admin panel under System > Extensions > Integrations. During configuration, provide a callback URL and an identity link URL.
The callback URL specifies where Commerce should send OAuth credentials during the token exchange process. The identity link URL points to the login page of the third-party application that integrates with Commerce, enabling proper authentication.

When creating an integration, a merchant can choose Save and Activate immediately. Alternatively, the merchant can activate a previously saved integration by clicking Activate from the Integrations grid.
Once the integration is created, Commerce generates a consumer key and a consumer secret.
Activating the integration sends these credentials to the endpoint specified during integration setup. Commerce performs an HTTP POST to the integration endpoint, including the following attributes:
- store_base_url
oauth_verifieroauth_consumer_keyoauth_consumer_secret
Integrations use the oauth_consumer_key key to get a request token and the oauth_verifier to get an access token.
OAuth handshake details
The process of completing the OAuth handshake requires that you,
- Get a request token
- Get an access token
Get a request token
A request token is a temporary token that the user exchanges for an access token. Use the following API to get a request token from Commerce:
POST /oauth/token/request
You must include these request parameters in the Authorization header in the call:
| PARAMETER | DESCRIPTION |
| oauth_consumer_key | The consumer key is generated when you create the integration. |
| oauth_signature_method | The name of the signature method used to sign the request. Must be the value HMAC-SHA256. |
| oauth_signature | A generated value (signature) |
| oauth_nonce | A random value that is uniquely generated by the application. |
| oauth_timestamp | A positive integer, expressed in the number of seconds since January 1, 1970 00:00:00 GMT. |
| oauth_version | The OAuth version. |
The response contains these fields:
1) oauth_token – The token to be used when requesting an access token.
2) oauth_token_secret – A secret value that establishes ownership of the token.
The response looks like this:
oauth_token=4cqw0r7vo0s5goyyqnjb72sqj3vxwr0h&oauth_token_secret=rig3x3j5a9z5j6d4ubjwyf9f1l21itrr
Get an access token
The request token must be exchanged for an access token. Use the following API to get an access token from Commerce:
POST /oauth/token/access
You must include these request parameters in the Authorization header in the call:
This process is known as a 2-legged OAuth handshake.
| PARAMETER | DESCRIPTION |
| oauth_consumer_key | The consumer key value that you retrieve after you register the integration. |
| oauth_nonce | A random value that is uniquely generated by the application. |
| oauth_signature | A generated value (signature) |
| oauth_signature_method | The name of the signature method used to sign the request. Must be the value HMAC-SHA256. |
| oauth_timestamp | A positive integer, expressed in the number of seconds since January 1, 1970 00:00:00 GMT. |
| oauth_version | The OAuth version. |
| oauth_token | The oauth_token value, or request token, obtained in Get a request token. |
| oauth_verifier | The verification code that is tied to the consumer and request token. It is sent as part of the initial POST operation when the integration is activated. |
The response looks like this:
oauth_token=0lnuajnuzeei2o8xcddii5us77xnb6v0&oauth_token_secret=1c6d2hycnir5ygf39fycs6zhtaagx8pd
Access the web APIs
After you authorize an integration to make API calls, third-party applications registered as integrations can invoke web APIs using the access token.
To make a web API call with the access token, include it in your request. For example:
GET /rest/V1/products/1
Ensure that you include the required parameters in the Authorization header of your request. This allows the API to authenticate the integration and grant access to the requested resource:
- oauth_consumer_key
- oauth_nonce
- oauth_signature_method
- oauth_signature
- oauth_timestamp
- oauth_token
The OAuth signature
All OAuth handshake requests and Web API calls include a signature in the Authorization header. You generate this signature using the following process:
First, concatenate a set of URL-encoded attributes and parameters to create the signature base string. These include:
- HTTP method
- URL
- oauth_nonce
- oauth_signature_method
- oauth_timestamp
- oauth_version
- oauth_consumer_key
- oauth_token
Next, apply the HMAC-SHA256 signature method. Construct the signing key by concatenating the consumer secret and token secret, separated by an ampersand (&), even if one of the values is empty.
Finally, ensure that you encode each parameter using URL parameter encoding before including it in the signature. This process guarantees that the OAuth request is properly signed and authenticated.
OAuth token exchange example to secure Magento 2 API
The scripts in this document simulate the Commerce OAuth 1.0a token exchange flow. You can place these scripts in the document root of your installation to expose them as endpoints. Your system can then interact with these endpoints to mimic the token exchange process.
Follow these steps for the OAuth 1.0a token exchange:
Click the edit icon for the integration and review the Integration Details on the Integration Info tab. You will see all the credentials required to make authenticated API requests using OAuth 1.0.
- Log in to your Admin panel and navigate to System > Extensions > Integrations.
- Click Add New Integration.
- Complete all fields in the Integration Info tab:
- Name: SomeUniqueIntegrationName
- Callback URL: http://your_app_host/endpoint.php
- Identity link URL: http://your_app_host/login.php
Then, configure permissions as needed on the API tab.
- From the drop-down menu, select Save and Activate.
- A pop-up window will appear, confirming the API permissions. Click Allow. (Ensure your browser allows pop-ups.) This action posts the credentials to endpoint.php. Another pop-up opens the login.php script for the identity linking step.
- Click Login. (The script simulates login, so it does not perform a real authentication check.) The checklogin.php script receives the posted credentials and completes the token exchange process.
- After the token exchange finishes successfully, the system redirects you back to the Integrations grid. The newly created integration should now appear in the Active state.
- Click the edit icon for the integration and review the Integration Details on the Integration Info tab. You will see all the credentials required to make authenticated API requests using OAuth 1.0.
checklogin.php
<?php
require './vendor/autoload.php';
$consumerKey = $_REQUEST['oauth_consumer_key'];
$callback = $_REQUEST['callback_url'];
session_id('test');
session_start();
/** Use $consumerKey to retrieve the following data in case it was stored in DB when received at "endpoint.php" */
if ($consumerKey !== $_SESSION['oauth_consumer_key']) {
throw new \Exception("Consumer keys received on different requests do not match.");
}
$consumerSecret = $_SESSION['oauth_consumer_secret'];
$magentoBaseUrl = rtrim($_SESSION['store_base_url'], '/');
$oauthVerifier = $_SESSION['oauth_verifier'];
define('TESTS_BASE_URL', $magentoBaseUrl);
$credentials = new \OAuth\Common\Consumer\Credentials($consumerKey, $consumerSecret, $magentoBaseUrl);
$oAuthClient = new OauthClient($credentials);
$requestToken = $oAuthClient->requestRequestToken();
$accessToken = $oAuthClient->requestAccessToken(
$requestToken->getRequestToken(),
$oauthVerifier,
$requestToken->getRequestTokenSecret()
);
header("location: $callback");
endpoint.php
<?php
session_id('test');
session_start();
// If this data is stored in the DB, oauth_consumer_key can be used as ID to retrieve this data later in "checklogin.php"
// For simplicity of this sample, it is stored in session
$_SESSION['oauth_consumer_key'] = $_POST['oauth_consumer_key'];
$_SESSION['oauth_consumer_secret'] = $_POST['oauth_consumer_secret'];
$_SESSION['store_base_url'] = $_POST['store_base_url'];
$_SESSION['oauth_verifier'] = $_POST['oauth_verifier'];
session_write_close();
header("HTTP/1.0 200 OK");
echo "Response";
login.php
<?php
$consumerKey = $_REQUEST['oauth_consumer_key'];
$callbackUrl = urlencode(urldecode($_REQUEST['success_call_back']));
echo <<<HTML
<table width="300" border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC">
<tr>
<form name="form1" method="post" action="checklogin.php?oauth_consumer_key={$consumerKey}&callback_url={$callbackUrl}">
<td>
<table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF">
<tr>
<td colspan="3"><strong>Integrations Login</strong></td>
</tr>
<tr>
<td width="78">Username</td>
<td width="6">:</td>
<td width="294"><input name="myusername" type="text" id="myusername"></td>
</tr>
<tr>
<td>Password</td>
<td>:</td>
<td><input name="mypassword" type="text" id="mypassword"></td>
</tr>
<tr>
<td> </td>
<td> </td>
<td><input type="submit" name="Submit" value="Login"></td>
</tr>
</table>
</td>
</form>
</tr>
</table>
HTML;
OauthClient.php
<?php
use OAuth\Common\Consumer\Credentials;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\OAuth1\Service\AbstractService;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\OAuth1\Token\TokenInterface;
class OauthClient extends AbstractService
{
/** @var string|null */
protected $_oauthVerifier = null;
public function __construct(
Credentials $credentials,
ClientInterface $httpClient = null,
TokenStorageInterface $storage = null,
SignatureInterface $signature = null,
UriInterface $baseApiUri = null
) {
if (!isset($httpClient)) {
$httpClient = new \OAuth\Common\Http\Client\StreamClient();
}
if (!isset($storage)) {
$storage = new \OAuth\Common\Storage\Session();
}
if (!isset($signature)) {
$signature = new \OAuth\OAuth1\Signature\Signature($credentials);
}
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
}
/**
* @return UriInterface
*/
public function getRequestTokenEndpoint()
{
return new Uri('http://my.host/oauth/token/request');
}
/**
* Returns the authorization API endpoint.
*
* @throws \OAuth\Common\Exception\Exception
*/
public function getAuthorizationEndpoint()
{
throw new \OAuth\Common\Exception\Exception(
'The REST API is 2-legged. Current operation is not available.'
);
}
/**
* Returns the access token API endpoint.
*
* @return UriInterface
*/
public function getAccessTokenEndpoint()
{
return new Uri('http://magento.host/oauth/token/access');
}
/**
* Parses the access token response and returns a TokenInterface.
*
* @param string $responseBody
* @return TokenInterface
*/
protected function parseAccessTokenResponse($responseBody)
{
return $this->_parseToken($responseBody);
}
/**
* Parses the request token response and returns a TokenInterface.
*
* @param string $responseBody
* @return TokenInterface
* @throws TokenResponseException
*/
protected function parseRequestTokenResponse($responseBody)
{
$data = $this->_parseResponseBody($responseBody);
if (isset($data['oauth_verifier'])) {
$this->_oauthVerifier = $data['oauth_verifier'];
}
return $this->_parseToken($responseBody);
}
/**
* Parse response body and create oAuth token object based on parameters provided.
*
* @param string $responseBody
* @return StdOAuth1Token
* @throws TokenResponseException
*/
protected function _parseToken($responseBody)
{
$data = $this->_parseResponseBody($responseBody);
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
/**
* Parse response body and return data in array.
*
* @param string $responseBody
* @return array
* @throws \OAuth\Common\Http\Exception\TokenResponseException
*/
protected function _parseResponseBody($responseBody)
{
if (!is_string($responseBody)) {
throw new TokenResponseException("Response body is expected to be a string.");
}
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException("Error occurred: '{$data['error']}'");
}
return $data;
}
/**
* @override to fix since parent implementation from lib not sending the oauth_verifier when requesting access token
* Builds the authorization header for an authenticated API request
*
* @param string $method
* @param UriInterface $uri the uri the request is headed
* @param \OAuth\OAuth1\Token\TokenInterface $token
* @param $bodyParams array
* @return string
*/
protected function buildAuthorizationHeaderForAPIRequest(
$method,
UriInterface $uri,
TokenInterface $token,
$bodyParams = null
) {
$this->signature->setTokenSecret($token->getAccessTokenSecret());
$parameters = $this->getBasicAuthorizationHeaderInfo();
if (isset($parameters['oauth_callback'])) {
unset($parameters['oauth_callback']);
}
$parameters = array_merge($parameters, ['oauth_token' => $token->getAccessToken()]);
$parameters = array_merge($parameters, $bodyParams);
$parameters['oauth_signature'] = $this->signature->getSignature($uri, $parameters, $method);
$authorizationHeader = 'OAuth ';
$delimiter = '';
foreach ($parameters as $key => $value) {
$authorizationHeader .= $delimiter . rawurlencode($key) . '="' . rawurlencode($value) . '"';
$delimiter = ', ';
}
return $authorizationHeader;
}
}
3). Secure Magento 2 API using Session-based authentication
As a customer, you log in to the storefront using your customer credentials. Similarly, as an admin, you log in to the Admin panel with your admin credentials.
The web API framework then verifies your identity and authorizes access by using your active session information.
Customers can directly access resources that the webapi.xml configuration file marks with anonymous or self permissions. In contrast, admins can access resources assigned to their Admin profile.
For example, when a customer is logged in to the storefront and a JavaScript widget calls the self API, the system fetches the details of the logged-in customer:
GET /rest/V1/customers/me
Similarly, when an admin is logged in to the Admin panel and a JavaScript widget calls the Magento_Customer::group API, the system retrieves details for the logged-in admin. Here, the web API framework identifies the admin from the active session and authorizes access to the Magento_Customer::group resource.
Currently, API endpoints do not support session-based authentication for admins.
Additionally, session-based authentication works only for AJAX calls. You cannot make direct browser requests because they expose security vulnerabilities.
For technical assistance, please get in touch with us via email at [email protected].
Discover powerful solutions to enhance your Magento 2 store by exploring our Magento 2 plugins page.
Bring your vision to life with custom-built solutions—hire skilled Magento 2 developers today.
Happy Coding!!

Be the first to comment.