I'm attempting to use the new kinde/expo module (version 0.1.2-23) and I'm seeing a couple of errors which appear to be preventing any further progress.
ERROR Invalid id token Signature verification failed
ERROR Invalid access token Signature verification failed
Any ideas?
Hi John, sorry to see that you are blocked from progressing further. I will need to raise this with a team member who knows the Expo SDK the best. I will get back to you on Monday.
This just started working. No idea why it was failing and no idea what changed to make it work π€¦
Any news on updates to the library? The latest code is still at 0.1.1 last time I checked.
Updates to peer dependencies to support react-native 76.1 would be good. Having the Kinde library available out of the box as a Provider and hook is a huge improvement by the way. Makes it very easy to use. The documentation should be updated to highlight that this library is available for Expo.
Thanks for describing these John, I will rely this back to the team and let you know if we already are working on them.
The library doesn't seem to handle expired tokens. It returns stale tokens from the secure store instead of checking the validity of the token returned from the store and getting a refreshed token if needed.
I'm getting these same two errors, and haven't been able to work out why.
ERROR Invalid id token Signature verification failed
ERROR Invalid access token Signature verification failed
The errors come from the Kinde Expo module itself.
Thank you for giving more information here, we have been working on improvements on token refresh, we will review what could be happening here and look to get this fixed up.
Done a bit more digging. The error seems to be in the jwt-validator library. I've expanded the logging in the code and it looks like my global.crypto is null so the verification fails. Why it was working and now isn't I can't figure out at all.
Hmm. Ignore that, it seems like it should fail to the jsrsasign library instead if that's the case.
Hi. Any update on the tokens not refreshing properly? We've seen this a couple of times now. It still appears that the expo library is returning the token out of secure storage without validating the expiry date of it.
Here's the error as seen on the Express side of the API call. The token sent from the Expo client is stale. It looks like the Expo SDK is pulling the token from the Expo SecureStore and not validating the date is still OK on it.
The app has been used daily with the same token and this error appears after the token expires.
Token not valid!
Error: Token expired at 2024-11-25T11:24:59.000Z
at validateJwtFields (C:\Users\John\Documents\Code\Alpha\alpha-app\node_modules\@kinde-oss\kinde-node-express-api\dist\cjs\index.js:922:19)
at verifyDecomposedJwt (C:\Users\John\Documents\Code\Alpha\alpha-app\node_modules\@kinde-oss\kinde-node-express-api\dist\cjs\index.js:995:9)
at process.processTicksAndRejections (c:\Users\John\Documents\Code\Alpha\alpha-app\lib\internal\process\task_queues.js:95:5)
at async C:\Users\John\Documents\Code\Alpha\alpha-app\node_modules\@kinde-oss\kinde-node-express-api\dist\cjs\index.js:1323:23 {failedAssertion: {β¦}, stack: 'Error: Token expired at 2024-11-25T11:24:59.0β¦node-express-api\\dist\\cjs\\index.js:1323:23', message: 'Token expired at 2024-11-25T11:24:59.000Z'}
arg0: Error: Token expired at 2024-11-25T11:24:59.000Z\n at validateJwtFields (C:\Users\John\Documents\Code\Alpha\alpha-app\node_modules\@kinde-oss\kinde-node-express-api\dist\cjs\index.js:922:19)\n at verifyDecomposedJwt (C:\Users\John\Documents\Code\Alpha\alpha-app\node_modules\@kinde-oss\kinde-node-express-api\dist\cjs\index.js:995:9)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async C:\Users\John\Documents\Code\Alpha\alpha-app\node_modules\@kinde-oss\kinde-node-express-api\dist\cjs\index.js:1323:23 {failedAssertion: {β¦}, stack: 'Error: Token expired at 2024-11-25T11:24:59.0β¦node-express-api\\dist\\cjs\\index.js:1323:23', message: 'Token expired at 2024-11-25T11:24:59.000Z'}
failedAssertion: {actual: 1732533899, expected: undefined}
actual: 1732533899
expected: undefined
Hi John, We are updating a heap of SDKs due to a token refresh issue. While we work on that, you can access a refresh method in the js.utils library here. Let me know if this helps for now. https://github.com/kinde-oss/js-utils
Hey lads, any updates on this issue? @kinde-oss/expo still has this issue, which leads to silly user experience. Maybe you can suggest any workarounds for this?
@Daniel Rivers @Claire - Kinde
Hey @Max Barinov we did a new release of Expo last week. Can you install and see if the issue persists? https://github.com/kinde-oss/expo
Apologies you weren't notified sooner.
Hey @Claire - Kinde I just verified that we use the latest release, 0.2.0. Issue is still exist. As a temporary solution, I decode a token and if it's expired, just clear secure storage.
When I try the new 0.2.0 library, on login
const token = await kinde.login({});
{ "success": false, "errorMessage": "No discovery document" }
<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/.well-known/openid-configuration">https://csnapit-seahorse.eu.kinde.com/.well-known/openid-configuration</a>
If I add this code to my app
import { useAutoDiscovery } from "expo-auth-session"; const discovery = useAutoDiscovery("<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com">https://auth.csnapit.com</a>"); console.log("Kinde Discovery Document:", discovery);
Kinde Discovery Document: {"authorizationEndpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/oauth2/auth">https://auth.csnapit.com/oauth2/auth</a>", "discoveryDocument": {"authorization_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/oauth2/auth">https://auth.csnapit.com/oauth2/auth</a>", "claims_supported": ["aud", "exp", "iat", "iss", "sub"], "code_challenge_methods_supported": ["S256"], "end_session_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/logout">https://auth.csnapit.com/logout</a>", "id_token_signing_alg_values_supported": ["RS256"], "introspection_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/oauth2/introspect">https://auth.csnapit.com/oauth2/introspect</a>", "issuer": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com">https://auth.csnapit.com</a>", "jwks_uri": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/.well-known/jwks">https://auth.csnapit.com/.well-known/jwks</a>", "request_uri_parameter_supported": false, "response_modes_supported": ["form_post", "query", "fragment"], "response_types_supported": ["code", "token", "id_token", "code token", "code id_token", "id_token token", "code id_token token"], "revocation_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/oauth2/revoke">https://auth.csnapit.com/oauth2/revoke</a>", "scopes_supported": ["address", "email", "offline", "openid", "phone", "profile"], "subject_types_supported": ["public"], "token_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/oauth2/token">https://auth.csnapit.com/oauth2/token</a>", "token_endpoint_auth_methods_supported": ["client_secret_post"], "userinfo_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/oauth2/v2/user_profile">https://auth.csnapit.com/oauth2/v2/user_profile</a>"}, "endSessionEndpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/logout">https://auth.csnapit.com/logout</a>", "registrationEndpoint": undefined, "revocationEndpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/oauth2/revoke">https://auth.csnapit.com/oauth2/revoke</a>", "tokenEndpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/oauth2/token">https://auth.csnapit.com/oauth2/token</a>", "userInfoEndpoint": "<a target="_blank" rel="noopener noreferrer" href="https://auth.csnapit.com/oauth2/v2/user_profile">https://auth.csnapit.com/oauth2/v2/user_profile</a>"}
Here you go.
https://github.com/tintop2k/kinde-test
This is the output I get when running and pressing the Sign In button.
(NOBRIDGE) LOG Kinde Discovery Document: {"authorizationEndpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/oauth2/auth">https://csnapit-seahorse.eu.kinde.com/oauth2/auth</a>", "discoveryDocument": {"authorization_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/oauth2/auth">https://csnapit-seahorse.eu.kinde.com/oauth2/auth</a>", "claims_supported": ["aud", "exp", "iat", "iss", "sub"], "code_challenge_methods_supported": ["S256"], "end_session_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/logout">https://csnapit-seahorse.eu.kinde.com/logout</a>", "id_token_signing_alg_values_supported": ["RS256"], "introspection_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/oauth2/introspect">https://csnapit-seahorse.eu.kinde.com/oauth2/introspect</a>", "issuer": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com">https://csnapit-seahorse.eu.kinde.com</a>", "jwks_uri": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/.well-known/jwks">https://csnapit-seahorse.eu.kinde.com/.well-known/jwks</a>", "request_uri_parameter_supported": false, "response_modes_supported": ["form_post", "query", "fragment"], "response_types_supported": ["code", "token", "id_token", "code token", "code id_token", "id_token token", "code id_token token"], "revocation_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/oauth2/revoke">https://csnapit-seahorse.eu.kinde.com/oauth2/revoke</a>", "scopes_supported": ["address", "email", "offline", "openid", "phone", "profile"], "subject_types_supported": ["public"], "token_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/oauth2/token">https://csnapit-seahorse.eu.kinde.com/oauth2/token</a>", "token_endpoint_auth_methods_supported": ["client_secret_post"], "userinfo_endpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/oauth2/v2/user_profile">https://csnapit-seahorse.eu.kinde.com/oauth2/v2/user_profile</a>"}, "endSessionEndpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/logout">https://csnapit-seahorse.eu.kinde.com/logout</a>", "registrationEndpoint": undefined, "revocationEndpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/oauth2/revoke">https://csnapit-seahorse.eu.kinde.com/oauth2/revoke</a>", "tokenEndpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/oauth2/token">https://csnapit-seahorse.eu.kinde.com/oauth2/token</a>", "userInfoEndpoint": "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com/oauth2/v2/user_profile">https://csnapit-seahorse.eu.kinde.com/oauth2/v2/user_profile</a>"} (NOBRIDGE) ERROR Login Failed: {"errorMessage": "No discovery document", "success": false}
............
Updating to this fixes it. I assumed from your updated README that the https:// should be removed...
export default function App() { return ( <KindeAuthProvider config={{ domain: "<a target="_blank" rel="noopener noreferrer" href="https://csnapit-seahorse.eu.kinde.com">https://csnapit-seahorse.eu.kinde.com</a>", clientId: "98d0959ecd8b4157bca6970f4e7b20f2", scopes: "openid profile email offline", }}> <Authentication /> </KindeAuthProvider> ); }
You should change your README to this or check the URL and add the https:// to the front if needed π
export default function App() { return ( <KindeAuthProvider config={{ domain: "<a target="_blank" rel="noopener noreferrer" href="https://your-app.kinde.com">https://your-app.kinde.com</a>", // Required clientId: "your-client-id", // Required // Optional (default: "openid profile email offline") scopes: "openid profile email offline", }}> <!-- Your application code --> </KindeAuthProvider> ); }
Oh, thanks for pointing this out. I will get this fixed up. Sorry for the confusion. Pleased you're working now