Hello and thank you for your explanation: We can still optimize the policy of token expiration using the AsJwT Object as bellow :
<set-variable name="token-exp" value="@{
// Extract the JWT (JSON Web Token) from the 'token' variable
Jwt jwt = ((String)context.Variables["token"]).AsJwt();
// Get the expiration time as a DateTime
DateTime exp = (DateTime)jwt.ExpirationTime;
// Return the expiration time formatted as "MM-dd-yyyy HH:mm:ss"
return exp.ToString("MM-dd-yyyy HH:mm:ss");
}" />
We can also set the cache expiration to the token validity time for better optimization :
<!-- Calculate the time left until token expiration in seconds -->
<set-variable name="tokenExpTimeLeftInSeconds" value="@((int)(Math.Round((DateTime.Parse((String)context.Variables["token-exp"]) - DateTime.UtcNow).TotalSeconds)))" />
<!-- Cache the token and its expiration time -->
<cache-store-value key="{{dawinci-ao-backend-url}}-token-key" value="@((String)context.Variables["token"])" duration="@((int)context.Variables["tokenExpTimeLeftInSeconds"])" caching-type="internal" />
<cache-store-value key="{{dawinci-ao-backend-url}}-token-exp-key" value="@((String)context.Variables["token-exp"])" duration="@((int)context.Variables["tokenExpTimeLeftInSeconds"])" caching-type="internal" />
For better resilience, I suggest handling errors in case of token retrieval failure, like bellow :
<choose>
<when condition="@(!context.Variables.ContainsKey("token") ||
!context.Variables.ContainsKey("token-exp") ||
(context.Variables.ContainsKey("token") &&
context.Variables.ContainsKey("token-exp") &&
(DateTime.Parse((String)context.Variables["token-exp"]).AddMinutes(-1.0)
<= DateTime.UtcNow)
)
)">
<!-- Send a request to obtain a new token -->
<send-request mode="new" response-variable-name="oauth_response" timeout="10" ignore-error="true">
<set-url>{{auth-url}}</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
<set-body>@{
string grant_type = "client_credentials";
string scope = "scope";
string client_id = "client_id";
string client_secret = "{{client-secret}}";
return $"grant_type={grant_type}&scope={scope}&client_id={client_id}&client_secret={client_secret}";
}</set-body>
</send-request>
<choose>
<when condition="@(((IResponse)context.Variables["oauth_response"]).StatusCode != 200)">
<!-- Handle error when obtaining the token -->
<return-response>
<set-status code="500" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>{
"error_code": "InternalServerError",
"error_message": "Internal server error occurred, Please try again later.",
"details": {
"source": "Token Exchange"
}
}</set-body>
</return-response>
</when>
</choose>