Welcome to the Kinde community

Updated 22 hours ago

Kinde/expo module errors: invalid id and access token signatures

At a glance

The community member is experiencing issues with the Kinde/Expo module (version 0.1.2-23), receiving errors related to invalid ID and access tokens. Other community members have also encountered similar problems, and the team is working on improvements to address the token refresh issue. A potential solution is to use the refresh method in the js.utils library, which the team has suggested. The community members have provided detailed information about the errors and their attempts to troubleshoot the issue.

Useful resources

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?

2
P
J
D
30 comments

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 🀦

Hey thats very bizzare! But great to hear that its working for you now.

Any news on updates to the library? The latest code is still at 0.1.1 last time I checked.

we do have further developments in the work. Is there anything you would like to see?

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

I'll check if there is an update.

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({});

The token returned equals this

{
  "success": false,
  "errorMessage": "No discovery document"
}

I've checked the discovery document URL, and that all seems OK.

<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>

Hi, John,

Could you share with me the KindeAuthProvider code from your application please?

Are you getting this on iOS or Android @John Edwards ?

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);

I get this output. So your autodiscovery is working OK.

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>"}

I solely test on Android, are you able to share a minimal repoduction repo?

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

I was sure I'd tried adding that before in my code. It's always the simple things!

Add a reply
Sign up and join the conversation on Slack