How to Implement the Refresh Token
Flexiti follows the Oauth 2 Authorization Method standard: https://oauth.net/2/
In order to call every POS-API Method an Access Token is required. By Default the Access Token is valid for 20 minutes. To get a valid Access Token a call must be made to the POST /oauth/token method endpoint.
Keeping an Access Token Valid
In order to always have a valid access token, the API Model Class should implement the refresh token functionality.
Client Credential vs Refresh Token
Both must be sent as the value of the grant_type parameter:
client_credential: The first call to the POST Oauth Authorization method must be made using this value. This should be stored in the user session. For the remainder of this document, we will refer to this as the "Client Credential Call".
refresh_token: All of the rest of the calls to the POST Oauth Authorization method must be made using this value along with the refresh_token parameter as the value of the last access_token stored in the session. For the remainder of this document, we will refer to this as the "Refresh Token Call".
See POST /oauth/token for more information
Has the Access Token Expired?
Flexiti recommends the Merchant website to have a isAccessTokenExpired function. Additionally it should have a constant called FLX_EXPIRATION_TIME_THRESHOLD. The FLX_EXPIRATION_TIME_THRESHOLD will be used to control the expiration time of an access_token.
Every access_token has a 20 minute lifespan, but since this is not controlled by the site we must have an independent reference to control it. This will be set in seconds, and set to 60 seconds by default.
The expiration_time should be stored in session along with the access_token and a accessTokenCreatedTime for it.
The logic condition should be:
(nowInSeconds - accessTokenCreatedTime >= accessTokenExpirationTime – FLX_EXPIRATION_TIME_THRESHOLD)
We consider an access_token valid when it has a life from 0 to expiration_time - FLX_EXPIRATION_TIME_THRESHOLD.
This will ensure that we can make use of the refresh token call when it's necessary, and in the case of an apply or a purchase the new access_token will be refreshed in order to give the user enough time to complete the entire flow.
Example PHP Code
Below you can see suggested code on how to handle the token and expiration.
private function isAccessTokenExpired($accessTokenCreatedTime, $accessTokenExpirationTime){
$nowInSeconds = time();
$limitThresholdInSeconds = $accessTokenExpirationTime - self::FLX_EXPIRATION_TIME_THRESHOLD;
return ($nowInSeconds - $accessTokenCreatedTime >= $limitThresholdInSeconds);
}
/**
* Get the authorization token for the next calls
* @return json The api response
*/
private function getFlexitiToken($getFlxAccessTokenFromCache = false){
$flxAccessToken = (null !== $this->session->getFlxOauthToken()) ? json_decode($this->session->getFlxOauthToken()) : null;
$flxAccessTokenCreatedTime = $this->session->getFlxAccessTokenCreatedTime();
$flxAccessTokenExpiresIn = $this->session->getFlxAccessTokenExpiresIn();
if ( isset($flxAccessToken)
&& !empty($flxAccessToken)
&& !$this->isAccessTokenExpired($flxAccessTokenCreatedTime, $flxAccessToken->expires_in)
)
{ //REFRESH TOKEN or CACHE
if ($getFlxAccessTokenFromCache){ //CACHE SHOULD BE TRUE ONLY FOR CALCULATOR CALLS
return $flxAccessToken;
}
$oAuthParams["grant_type"] = "refresh_token";
$oAuthParams["refresh_token"] = $flxAccessToken->refresh_token;
}else{ // ASK FOR A NEW ACCESS TOKEN
$oAuthParams["grant_type"] = "client_credentials";
}
$oAuthParams["client_id"] = $this->getConfig('clientid');
$oAuthParams["client_secret"] = $this->getConfig('clientsecret');
$url = $this->getConfig('api_url') ."flexiti/online-api/oauth/token";
try {
$response=$this->curlCall($url, $oAuthParams);
} catch (\Exception $e) {
$this->logger->critical('Flexiti Auth/token cUrl error', ['exception' => $e]);
$message = __("Flexiti Auth/token cUrl error:\n {$e->getMessage()}");
throw new Exception($message);
}
$responseFlxAccessToken = json_decode($response);
$this->httpDebug($url, $oAuthParams, $this->curl->getStatus(), $responseFlxAccessToken, null);
//STORE TOKEN DATA IN SESSION
$this->session->setFlxOauthToken(json_encode($responseFlxAccessToken));
$this->session->setFlxAccessTokenCreatedTime(time());
return $responseFlxAccessToken;
}