In magento 2.4.4p4 enterprise edition I noticed when generating access token using the code below
// MagentoCustomerApiAccountManagementInterface;
$customer = $this->customerAccountManagement->authenticate($username, $password);
// MagentoIntegrationModelOauthTokenFactory
$token = $this->tokenModelFactory->create();
$token->createCustomerToken($customer->getId());
$accessToken = $token->getToken();
return [[
'accessToken'=>$accessToken,
'customer_id'=>$customer->getId()
]];
The accessToken I received value is as below
eyJraWQiOiIxIiwiYWxnIjoiSFMyNTYifQ.eyJ1aWQiOjM1NTk2OSwidXR5cGlkIjozLCJpYXQiOjE3MjMwMjQwMjQsImV4cCI6MTcyMzAyNzYyNH0.QARVztXCFzK6k867g0ulsHPIFOx1GqlWQGKZ4-uBD5M
Which I believe is a JWT Token generated by magento 2.4.4p4 ( JWT because i noticed it has 3 json objects encoded as base-64 strings, concatenated together with full-stop characters, source of reading: https://newbury.me/2022/05/25/jwts-for-api-authentication-in-magento-2/ )
I am actually in the progress of creating a custom login API and custom logout API , but since this JWT Token does not get stored in oauth_token upon the code above is triggered I am not able to retrieve or revoke the token
Appreciate anyone that can help provide guidance how to create custom login and logout function in Magento 2.4.4p4 , I am using the Enterprise version of magento
Attached below is the source code for my login and logout function
<?php
namespace WowshopMobileAppApiModel;
use WowshopMobileAppApiApiCustomerInterface;
use MagentoFrameworkAppResponseInterface;
use MagentoFrameworkControllerResultFactory;
use MagentoCustomerApiAccountManagementInterface;
use MagentoIntegrationModelOauthTokenFactory;
use WowshopApiSystemHelperData as ApiHelper;
use MagentoCustomerApiCustomerRepositoryInterface;
use MagentoSalesModelResourceModelOrderCollectionFactory as OrderCollectionFactory;
use MagentoCustomerModelSession;
use MagentoCustomerModelSessionFactory;
use MagentoCustomerModelCustomer as CustomerModel;
use MagentoJwtUserTokenModelReader as JwtReader;
class Customer implements CustomerInterface
{
protected $tokenModelFactory;
protected $customerAccountManagement;
protected $resultFactory;
protected $apiHelper;
public function __construct(
TokenFactory $tokenModelFactory,
AccountManagementInterface $customerAccountManagement,
ResultFactory $resultFactory,
MagentoFrameworkWebapiRestRequest $request,
ApiHelper $apiHelper,
CustomerRepositoryInterface $customerRepository,
OrderCollectionFactory $orderCollectionFactory,
Session $customerSession,
SessionFactory $customerSessionFactory,
CustomerModel $customerModel,
JwtReader $jwtReader
) {
$this->tokenModelFactory = $tokenModelFactory;
$this->customerAccountManagement = $customerAccountManagement;
$this->resultFactory = $resultFactory;
$this->request = $request;
$this->_apiHelper = $apiHelper;
$this->customerRepository = $customerRepository;
$this->orderCollectionFactory = $orderCollectionFactory;
$this->customerSession = $customerSession;
$this->customerSessionFactory = $customerSessionFactory;
$this->customerModel = $customerModel;
$this->jwtReader = $jwtReader;
}
/**
* Accept username and password and return token string
* @author : Farhan
*
* @api
* @param string $username
* @param string $password
* @return array
*/
public function login($username, $password)
{
$authenticationStatus = $this->_apiHelper->authenticateApiToken($this->request);
if(!$authenticationStatus['status']){
return [$authenticationStatus];
}
try {
$customer = $this->customerAccountManagement->authenticate($username, $password);
$token = $this->tokenModelFactory->create();
$token->createCustomerToken($customer->getId());
$accessToken = $token->getToken();
return [[
'accessToken'=>$accessToken,
'customer_id'=>$customer->getId()
]];
} catch (MagentoFrameworkExceptionLocalizedException $e) {
// Handle login failure
return ['error' => $e->getMessage()];
} catch (Exception $e) {
// Handle unexpected exceptions
return ['error' => $e->getMessage()];
}
}
/**
* POST retrieve customer self data
* @author : Farhan
*
* @api
* @return array
*/
public function viewCustomer()
{
$customer_id = $this->_apiHelper->getCustomerIdFromToken($this->request);
if (!$customer_id) {
throw new Exception("User not authenticated.");
}
try {
$customer = $this->customerRepository->getById($customer_id);
$address = $this->getCustomerAddresses($customer_id);
return [[
'customer_id'=>$customer_id,
'email'=>$customer->getEmail(),
'firstname'=>$customer->getFirstname(),
'lastname'=>$customer->getLastname(),
'gender'=>$customer->getGender(),
'address'=>$address
]];
} catch (MagentoFrameworkExceptionLocalizedException $e) {
// Handle login failure
return ['error' => $e->getMessage()];
} catch (Exception $e) {
// Handle unexpected exceptions
return ['error' => $e->getMessage()];
}
}
public function getCustomerAddresses($customerId) {
$customer = $this->customerRepository->getById($customerId);
$addresses = $customer->getAddresses();
$addressData = array();
foreach($addresses as $address){
$addressData[] = $this->getAddressData($address);
}
return $addressData;
}
private function getAddressData($address) {
$addressData = [
'address_id' => $address->getId(),
'customer_id' => $address->getCustomerId(),
'firstname' => $address->getFirstname(),
'lastname' => $address->getLastname(),
'street' => $address->getStreet(),
'city' => $address->getCity(),
'region' => $address->getRegion()->getRegion(),
'postcode' => $address->getPostcode(),
'country_id' => $address->getCountryId(),
'telephone' => $address->getTelephone()
];
return $addressData;
}
/**
* @author : Farhan
*
* @api
* @return array
*/
public function logout()
{
$authorizationBearer = $this->request->getHeader('Authorization');
$authorizationBearerArr = explode(' ', $authorizationBearer);
$accessToken = $authorizationBearerArr[1];
// this code able to read acccess token but I am unable to find ways to revoke it as it didnt get stored in oauth_table
$tokenJwt = $this->jwtReader->read($accessToken)->getUserContext();
$result = [
'revoke' => 'fail',
'delete' => 'fail'
];
try {
$authorizationBearer = $this->request->getHeader('Authorization');
$authorizationBearerArr = explode(' ', $authorizationBearer);
$accessToken = $authorizationBearerArr[1];
$token = $this->tokenModelFactory->create()->loadByToken($accessToken);
if (!$token->getToken()) {
$result['error'] = 'Invalid access token';
}
if ($token->getRevoked(true)) {
$result['error'] = 'Token already revoked';
}
if($token->setRevoked(true)->save()){
$result['revoke'] = 'success';
}
if($token->delete()){
$result['delete'] = 'success';
}
if ($token->getToken()) {
$result['error'] = 'Token fail to be deleted';
}
return [$result];
} catch (Exception $e) {
return ['error' => $e->getMessage()];
}
}
}