oidc-client
oidc-client copied to clipboard
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'refreshToken')
Issue and Steps to Reproduce
it happens after a long idle randomly. Still not sure how to reproduce it.
Versions
6.13.4
Screenshots
Expected
When that error happens, go to the session lost page or the auth error page
Actual
Throw the error and the page crashes.
Additional Details
- Installed packages: React
Hi @Zhuohui-Li ,
Do you have a sample of your configuration ? May you update to the latest version? Lastest version fixed a similar bug.
Hi @guillaume-chervet The config is
client_id:
redirect_uri:
scope:
authority:
refresh_time_before_tokens_expiration_in_second: 10,
service_worker_only: false,
storage: localStorage,
authority_configuration: {
},
@guillaume-chervet Some error info:
oidc:config_name:refreshTokensAsync_silent_error: {
"message": "bad request",
"tokenResponse": {
"success": false,
"status": 400
}
}
oidc:config_name:refreshTokensAsync_error: {
"message": "refresh token"
}
It happens in the latest version also after a really long idle (like overnight)
Hi @Zhuohui-Li , do you know the lifetime of your refresh token? And the lifetime of ypu cookie session with your oidc server?
Hello, we are experiencing similar issues, it is characterized by it trying to call fetch
POST to the /token endpoint repeatedly and getting a error 400, then it throws an error along the lines of the title of the issue. It mainly appears within seconds / minutes of opening a tab, but sometimes also when they reenter a tab after several hours.
(error message from various browsers: firefox: TypeError: c is null
, chrome / edge / opera: Cannot read properties of null (reading 'refreshToken')
, safari: null is not an object (evaluating 'c.refreshToken')
)
Our oidc configuration is as follows:
// Access Token Life : 30 minutes
AccessToken: 30 * 60,
// Refresh Token Life : 1 Week Refresh Token
RefreshToken: 60 * 60 * 24 * 7,
// ID Token Life : 15 minutes
IdToken: 15 * 60,
// Session Life 6 months
Session: 60 * 60 * 24 * 30 * 6,
},
Our client (this package) configuration is as follows:
export const DEFAULT_CONFIGURATION: OidcConfiguration = {
client_id: process.env['NEXT_PUBLIC_OIDC_CLIENT_ID'] ?? '',
redirect_uri: process.env['NEXT_PUBLIC_OIDC_REDIRECT_URL'] ?? '',
// we forcibly add openid & profile in our wrapper, but we have offline_access in every project
scope: process.env['NEXT_PUBLIC_OIDC_SCOPES'] ?? '',
authority: process.env['NEXT_PUBLIC_OIDC_AUTHORITY'] ?? 'https://boop.fynn.ai/oidc',
service_worker_only: false,
storage: window.localStorage
} as const;
We are using nextjs, but the OidcProvider is only activated once window != undefined (e.g. in the browser) because otherwise we get problems with using localStorage, and I believe nothing from the library is used before useOidc().isAuthenticated == true
and useOidcUser().oidcUserLoadingState == OidcUserStatus.Loaded
(we are using a small wrapper around the library).
Hi @TheChristophe thank you very much for all your information. It will help a lot. Which version are you using?
We are currently on 6.14.2, and I believe it also happened on an older version before
You can already set up token_renew_mode: PropTypes.string, // Optional, update tokens base on the selected token(s) lifetime: "access_token_or_id_token_invalid" (default), "access_token_invalid" , "id_token_invalid" Property to acceaccess_token_invalid, I think it will help to reduce token updates for your case. I have to reproduce your case.
Thank you @TheChristophe for the version :)
I will try the access_token_invalid
and keep an eye on whether we're still seeing it pop up, thanks
By random chance I've managed to reproduce the error in a staging environment too, in case this is useful:
It does not seem to crash or break the application in production at least, it just goes to the login screen on our application
The flow seems to be:
- the tokens are attempted to be requested here https://github.com/AxaGuilDEv/react-oidc/blob/master/packages/react/src/oidc/vanilla/oidc.ts#L449, but it fails (5 times) because
{"error":"invalid_grant","error_description":"grant request is invalid"}
- (...)
- it fails here https://github.com/AxaGuilDEv/react-oidc/blob/master/packages/react/src/oidc/vanilla/renewTokens.ts#L24 (
tokens
= null)
Because we use the same client ID in staging and local development I could copy the localStorage entry to reproduce the error on my local machine, I don't know what the issue is, but at least I found that if I change this https://github.com/AxaGuilDEv/react-oidc/blob/master/packages/react/src/oidc/vanilla/renewTokens.ts#L18
if (!oidc.tokens) {
await oidc.destroyAsync(status);
return;
}
to
if (!tokens || !oidc.tokens) {
await oidc.destroyAsync(status);
return;
}
the error stops appearing
Hi @guillaume-chervet I tried to connect with my auth provider team but no response yet. Here's my guess to reproduce it. During a long idle, the refresh token in the storage is expired. After the system wakes up it sends the expired refresh token to auth provider endpoint and then get a 400 error without any return value. After that the react-oidc library tries to read refreshToken from undefined and therefore throws the error.
Thank you @Zhuohui-Li , I sorry was busy.
I have an idea, I make some tests right now !
Hello,
I have the same problem when I stay idle too long (with version 6.14.3).
And once I refresh the page the problem is still here and I am stuck, the only way I can go the login page again is to stop the service worker by hand with the Chrome tools (maybe an error on my side for this part ?)
I think version 6.14.4 just publish fixed the bug. But I'am not sure.
Hello,
It worked for me, thank you very much !
Hi @guillaume-chervet It works well. Thanks a lot.
Thank you a lot for your feedbacks @Zhuohui-Li and @TheChristophe and @leonoredesplas
I'm still observing the issue in production after updating, I'm wondering if my issue is different (or people are accidentally still loading the old page). I'll keep an eye on it in the following days
Hi @TheChristophe , thank you for your feedback, i will make more tests with next and localStorage