Okta-auth-js idToken seems to disappear from okta-token-storage

We are using okta-auth-js integrated with our application code for auth. It works well but there is one odd behavior that I am trying to track down.

Here is a high-level view of how we are using it for authentication:

Subscribe to authStateManager and within the subscription check authState.isAuthenticated and if true set an internal app state for authentication. If the app is not authenticated then there is a check made using oktaAuth.isAuthenticated(). So if there are valid tokens stored in the browser store that call will return true and the app will set it’s state as authenticated.

Here is where the strange behavior comes in to play:
When authenticated if I check the browser application store there will be a okta-token-storage key that stores and object containing both an accessToken and an idToken. Closing the browser, reopening, and navigating to the site will pass authentication via the stored tokens for some amount of time, which I have not yet determined what that interval is yet. But if I navigate to the site after some amount of time, say an hour, isAuthenticated() returns false. Then if I look at okta-token-storage accessToken is there but the idToken property is missing. It’s also not a token expiration issue because the expiration time is far greater than the time interval that just elapsed, which I can verify with the accessToken that is still present.

From the okta-auth-js documentation

isAuthenticated: true if the user is considered authenticated. Normally this is true if both an idToken and an accessToken are present in the tokenManager

which would seem to indicate why it is returning false. But the question is what is happening to the idToken and why is it gone?

Are you sure its not related to the ID token expiring? Those have a lifetime of only 1hr.

How long does it take for you to see this behavior?

Ahhh yes that is correct. I thought they had the same expiresAt value but upon closer inspection you are correct the idToken does have a 1 hour expiration. Is the idToken refreshable?

Yup, the ID token should be able to be refreshed. If you’re using PKCE (enabled by default in newer versions of AuthJS), as long as you request offline_access scope, the library will refresh them for you via autoRenew.

Do you see a /token request being made around when the ID token is expiring?

No I do not see a /token request being made. Should there be a refresh token in okta-token-storage because there is not. Is there something from a configuration perspective with either the SDK or Okta cloud that needs to be done? In oktaConfig we do set autoRenew to true.

Wait, the refresh token is returned from call to /token with grant_type=refresh_token, right? But no, the SDK is not making a call to /token for an expired idToken that I can see.

Also, is it possible to revoke the idToken. For testing purposes if I pass the idToken along with a token_type_hint of id_token to /revoke it returns a 200 response but introspect on that token still shows it as active. If I do the same thing for an access_token it will return active=false.

Okay, I was able to get the refresh token to show up in token storage by adding offline_access to my auth server’s API access policy in the default policy rule and also adding the scope to my OktaAuth config. Now I guess I have to wait an hour for the token to expire to test the autoRenew functionality since I can’t find a way to force or change expiration.

I also have a problem adding offline_access to my default app’s grant which I’ll explain later, but for now I will see if the SDK will renew the IdToken after it expires.

1 Like

No, ID tokens aren’t used for access (authorization) and cannot be revoked.

Let me know how it goes once your app attempts a renewal with the refresh token it got back.

Yes, that worked, the SDK does make a call to /token and refresh the idToken . It does make it rather inconvenient to test though when you have to wait 1hr for the idToken to expire each iteration.

My other problem is that we have an additional Okta app providing the Device Grant Flow to authorize IOT devices and our server back-end code has logic that inspects the oauth scope looking for offline_access to determine if a request came from a client application or a device. I think that can be solved by adding another scope to the access policy rule used for the Device Authorization grant and check for that scope value instead.

Creating an additional new scope for the device authorization did the trick.

1 Like

It does make it rather inconvenient to test though when you have to wait 1hr for the idToken to expire each iteration.

If you want to make your testing a little quicker and you are using a Custom Authorization Server, you could look to set up a Token Inline Hook to modify the ID token lifetime (this is the only way you can change it). This is what I do in my test environments for exactly that reason.

There’s an example of what the response for your hook endpoint would need to be here. As the shortest lifetime you can set is 5 minutes, your hook could return this response to shorten the ID token lifetime to that:

{
  "commands": [
    {
      "value": [
        {
          "value": 300,
          "op": "replace",
          "path": "/token/lifetime/expiration"
        }
      ],
      "type": "com.okta.identity.patch"
    }
  ]
}

That would be helpful thanks for the tip!

1 Like

I thought of one other question if you don’t mind. For the custom scope that I added with existing access tokens that have not yet expired and do not include the new scope when the access token is refreshed will it pick up the new scope after the refresh?

If a refresh token is used, no, you will not be able to request/receive additional scopes during a refresh. You would instead need to make a new /authorize request with these additional scopes to get an access and refresh token that would contain them