logto-io / js

🤓 Logto JS SDKs.
https://docs.logto.io/quick-starts/
MIT License
67 stars 40 forks source link

bug: Invalid grant when trying to use getAccessToken in React app #503

Closed BartoszF closed 1 year ago

BartoszF commented 1 year ago

Describe the bug

Trying to get access token in my react app to communicate with backend.

Unfortunately Logto returns error:

{"error":"invalid_grant","error_description":"grant request is invalid"}

In Audit logs:

{
  "ip": "::ffff:172.19.0.1",
  "key": "ExchangeTokenBy.RefreshToken",
  "error": "{\"stack\":\"InvalidGrant: invalid_grant\\n    at refreshTokenHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/actions/grants/refresh_token.js:41:11)\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async callTokenHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/actions/token.js:70:7)\\n    at async allowedGrantTypeCheck (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/actions/token.js:53:7)\\n    at async supportedGrantTypeCheck (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/actions/token.js:45:7)\\n    at async stripGrantIrrelevantParams (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/actions/token.js:33:7)\\n    at async auth (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/shared/token_auth.js:257:9)\\n    at async loadClient (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/shared/token_auth.js:152:9)\\n    at async setWWWAuthenticateHeader (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/shared/token_auth.js:43:11)\\n    at async selectiveBody (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/shared/selective_body.js:49:5)\\n    at async noCache (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/shared/no_cache.js:3:3)\\n    at async errorHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/shared/error_handler.js:26:7)\\n    at async ensureSessionSave (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/helpers/initialize_app.js:52:7)\\n    at async contextEnsureOidc (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/shared/context_ensure_oidc.js:4:5)\\n    at async file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/helpers/initialize_app.js:222:5\\n    at async errorHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.0.0/node_modules/oidc-provider/lib/shared/error_handler.js:26:7)\",\"message\":\"invalid_grant\",\"allow_redirect\":true,\"name\":\"InvalidGrant\",\"error\":\"invalid_grant\",\"status\":400,\"statusCode\":400,\"expose\":true,\"error_description\":\"grant request is invalid\",\"error_detail\":\"refresh token not found\"}",
  "params": {
    "client_id": "rhlxa6u8rgw2jc1i4obsn",
    "grant_type": "refresh_token",
    "refresh_token": "tFkEQGqgj2lFlrlVfGC0gFNd0HTDAO4-BlPos6Diuw7"
  },
  "result": "Error",
  "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 OPR/98.0.0.0",
  "tokenTypes": [],
  "applicationId": "rhlxa6u8rgw2jc1i4obsn"
}

Data that lib is sending:

client_id=rhlxa6u8rgw2jc1i4obsn&refresh_token=tFkEQGqgj2lFlrlVfGC0gFNd0HTDAO4-BlPos6Diuw7&grant_type=refresh_token

Problem occurs with version ^2.0.0 and ^1.1.2. Docker image with tag latest

Expected behavior

Logto should properly return access token.

How to reproduce?

After adding API Resource in Admin panel.

const config: LogtoConfig = {
        endpoint: 'http://localhost:3001/',
        appId: 'rhlxa6u8rgw2jc1i4obsn',
        resources: ['http://localhost:8080']
    };

// After sign-in

const {getAccessToken} = useLogto();
await getAccessToken('http://localhost:8080');

Context

wangsijie commented 1 year ago

Thanks for reporting, will take a look

wangsijie commented 1 year ago

@BartoszF could you please provide a minimal, reproducible example?

lampkin-diet commented 1 year ago

Hey! I also have such error using cntr/sveltekit which uses such client under the hood:

 "node_modules/@logto/client": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/@logto/client/-/client-1.1.2.tgz",
      "integrity": "sha512-FPxHwB9mgdXd6uCI7/8jjDgRe1nfVvJe48g8J+DR+sZpXLTmU44vtKN89LBRoBcwIPlv3D6v1ySZW883E67FPw==",
      "dev": true,
      "dependencies": {
        "@logto/js": "^1.1.2",
        "@silverhand/essentials": "^2.6.1",
        "camelcase-keys": "^7.0.1",
        "jose": "^4.13.2",
        "lodash.get": "^4.4.2",
        "lodash.once": "^4.1.1"
      }
    },

My steps:

waltcow commented 1 year ago

same issue here

export const getServerSideProps: GetServerSideProps = logtoClient.withLogtoSsr(***,  {
    fetchUserInfo: true,
  })

$ab66c74b65acc6a3$export$ba60d77e6748b659 [Error]: Unexpected response error from the server.
    at file:///app/node_modules/@logto/client/lib/module.mjs:68:71
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async $ce6f2a62716522ae$export$9909137b467efb8b (file:///app/node_modules/@logto/js/lib/module.mjs:135:48)
    at async $0aca7ca5e7992ee0$export$2e2bcd8739ae039.getAccessTokenByRefreshToken (file:///app/node_modules/@logto/client/lib/module.mjs:240:133)
    at async $0aca7ca5e7992ee0$export$2e2bcd8739ae039.fetchUserInfo (file:///app/node_modules/@logto/client/lib/module.mjs:126:29)
    at async $0aca7ca5e7992ee0$export$2e2bcd8739ae039.getContext (file:///app/node_modules/@logto/node/lib/module.mjs:59:64)
    at async file:///app/node_modules/@logto/next/lib/module.mjs:79:30 {
  code: 'unexpected_response_error',

{
    error: 'invalid_grant',
    error_description: 'grant request is invalid'
  }
}
wangsijie commented 1 year ago

Thanks, will take a look

wangsijie commented 1 year ago

I tried with the following code:

const config: LogtoConfig = {
    appId,
    endpoint,
    scopes: [UserScope.Email, UserScope.Phone, UserScope.CustomData, UserScope.Identities],
    resources: ['http://localhost:8080'],
 };
useEffect(() => {
    (async () => {
      if (isAuthenticated) {
        const token = await getAccessToken('http://localhost:8080');
        console.log('token', token);
      }
    })();
  }, [getAccessToken, isAuthenticated]);

Everything goes fine, so could you guys please provide a minimal, reproducible example?

charIeszhao commented 1 year ago

Based on the original error message the OP posted, the detailed error message in the end shows: \"error_detail\":\"refresh token not found\".

It might be caused by using an invalid refresh token.

charIeszhao commented 1 year ago

@anikitinDSR @waltcow The invalid grant error can happen under various circumstances. Can you check the detailed error message from the audit logs, just like the OP does.

Typical reasons that might cause an invalid_grant error might be:

So there's no one silver bullet for all these issues. More context would be appreciated

odylewski commented 1 year ago

@charIeszhao @wangsijie I've just encountered a very similar issue.

In my case, a call to POST /oidc/token is being triggered twice. The first attempt succeeds and I'm able to retrieve the token. However, it is immediately followed by another request with the same payload (client_id, code, code_verifier) which expectedly fails as the token has already been issued (with the aforementioned 'grant request is invalid' error).

After some debugging I found out that the reason why the call is being made twice is React's StrictMode. Specifically, this paragraph explains the behavior:

(...) To help you find accidentally impure code, Strict Mode calls some of your functions (only the ones that should be pure) twice in development.

When I disable the Strict Mode the problem immediately goes away.

It seems the problem is somewhere in useHandleSignInCallback which does not properly work with Strict Mode enabled. Any chance you could take a look?

wangsijie commented 1 year ago

@odylewski Thanks for the feedback, I and @charIeszhao will take a look.

charIeszhao commented 1 year ago

Guys, we have made some fixes recently in the JS SDKs (#520). Please bump to the latest version and try again. Feel free to let us know if the issue persists.

patrickhilker commented 1 year ago

I still get the same error using @react/browser@2.1.1:

{
  "ip": "::ffff:172.18.0.1",
  "key": "ExchangeTokenBy.RefreshToken",
  "error": "{\"stack\":\"InvalidGrant: invalid_grant\\n    at refreshTokenHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/grants/refresh_token.js:73:11)\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async callTokenHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:70:7)\\n    at async allowedGrantTypeCheck (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:53:7)\\n    at async supportedGrantTypeCheck (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:45:7)\\n    at async stripGrantIrrelevantParams (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:33:7)\\n    at async auth (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:257:9)\\n    at async loadClient (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:152:9)\\n    at async setWWWAuthenticateHeader (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:43:11)\\n    at async selectiveBody (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/selective_body.js:49:5)\\n    at async noCache (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/no_cache.js:3:3)\\n    at async errorHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/error_handler.js:26:7)\\n    at async ensureSessionSave (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/helpers/initialize_app.js:52:7)\\n    at async contextEnsureOidc (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/context_ensure_oidc.js:4:5)\\n    at async file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/helpers/initialize_app.js:222:5\\n    at async errorHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/error_handler.js:26:7)\",\"message\":\"invalid_grant\",\"allow_redirect\":true,\"name\":\"InvalidGrant\",\"error\":\"invalid_grant\",\"status\":400,\"statusCode\":400,\"expose\":true,\"error_description\":\"grant request is invalid\",\"error_detail\":\"grant not found\"}",
  "params": {
    "resource": "https://api.xxx.com",
    "client_id": "mg81t20ajcsvaoo2h9i35",
    "grant_type": "refresh_token",
    "refresh_token": "yVRCJXJRwM4YLOq02WmUVaUgguHynMJXhaEpt3rgZWx"
  },
  "result": "Error",
  "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
  "tokenTypes": [],
  "applicationId": "mg81t20ajcsvaoo2h9i35"
}

From my package.json:


"dependencies": {
    "@logto/react": "^2.1.1",
},
"resolutions": {
    "@logto/browser": "2.1.1",
    "@logto/client": "2.2.2",
    "@logto/js": "2.1.2"
  }

Please let me know what else I need to provide.

bramhoven commented 1 year ago

I have the same issue although for me it is when the grand_type is authorization_code:

{
  "ip": "::ffff:172.19.0.1",
  "key": "ExchangeTokenBy.AuthorizationCode",
  "error": "{\"stack\":\"InvalidGrant: invalid_grant\\n    at authorizationCodeHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/grants/authorization_code.js:89:11)\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async callTokenHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:70:7)\\n    at async allowedGrantTypeCheck (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:53:7)\\n    at async supportedGrantTypeCheck (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:45:7)\\n    at async stripGrantIrrelevantParams (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:33:7)\\n    at async auth (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:257:9)\\n    at async loadClient (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:152:9)\\n    at async setWWWAuthenticateHeader (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:43:11)\\n    at async selectiveBody (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/selective_body.js:49:5)\\n    at async noCache (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/no_cache.js:3:3)\\n    at async errorHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/error_handler.js:26:7)\\n    at async ensureSessionSave (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/helpers/initialize_app.js:52:7)\\n    at async contextEnsureOidc (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/context_ensure_oidc.js:4:5)\\n    at async file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/helpers/initialize_app.js:222:5\\n    at async errorHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/error_handler.js:26:7)\",\"message\":\"invalid_grant\",\"allow_redirect\":true,\"name\":\"InvalidGrant\",\"error\":\"invalid_grant\",\"status\":400,\"statusCode\":400,\"expose\":true,\"error_description\":\"grant request is invalid\",\"error_detail\":\"authorization code already consumed\"}",
  "params": {
    "code": "GhlxlBTQUipmeJYqvptp0SvtigjP53N0grXQr5bTMig",
    "client_id": "arxx13ns81wgzxqwjcy5y",
    "grant_type": "authorization_code",
    "redirect_uri": "http://localhost:3000/callback",
    "code_verifier": "r6O-A3JqrVPr3BSQoImZJjpYLvQUXfQ59wVCQmtOvRDDlkXFwStFl32rq3-ZC-3XI1cxMEpsrH3ScqCr218YfQ"
  },
  "result": "Error",
  "userAgent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0",
  "tokenTypes": [],
  "applicationId": "arxx13ns81wgzxqwjcy5y"
}

Using @logto/react: ^2.1.1

waltcow commented 1 year ago

resolved by adding missing resources in LogtoProvider

const config: LogtoConfig = {
    appId,
    endpoint,
    scopes: [UserScope.Email, UserScope.Phone, UserScope.CustomData, UserScope.Identities],
    resources: ['http://localhost:8080'],
 };
bramhoven commented 1 year ago

My issue was that is was issuing token to quickly for getting user info. I fixed the logic so it would only retrieve it once after logging in and that solved it.

charIeszhao commented 1 year ago

I still get the same error using @react/browser@2.1.1:

{
  "ip": "::ffff:172.18.0.1",
  "key": "ExchangeTokenBy.RefreshToken",
  "error": "{\"stack\":\"InvalidGrant: invalid_grant\\n    at refreshTokenHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/grants/refresh_token.js:73:11)\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async callTokenHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:70:7)\\n    at async allowedGrantTypeCheck (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:53:7)\\n    at async supportedGrantTypeCheck (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:45:7)\\n    at async stripGrantIrrelevantParams (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:33:7)\\n    at async auth (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:257:9)\\n    at async loadClient (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:152:9)\\n    at async setWWWAuthenticateHeader (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:43:11)\\n    at async selectiveBody (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/selective_body.js:49:5)\\n    at async noCache (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/no_cache.js:3:3)\\n    at async errorHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/error_handler.js:26:7)\\n    at async ensureSessionSave (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/helpers/initialize_app.js:52:7)\\n    at async contextEnsureOidc (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/context_ensure_oidc.js:4:5)\\n    at async file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/helpers/initialize_app.js:222:5\\n    at async errorHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/error_handler.js:26:7)\",\"message\":\"invalid_grant\",\"allow_redirect\":true,\"name\":\"InvalidGrant\",\"error\":\"invalid_grant\",\"status\":400,\"statusCode\":400,\"expose\":true,\"error_description\":\"grant request is invalid\",\"error_detail\":\"grant not found\"}",
  "params": {
    "resource": "https://api.xxx.com",
    "client_id": "mg81t20ajcsvaoo2h9i35",
    "grant_type": "refresh_token",
    "refresh_token": "yVRCJXJRwM4YLOq02WmUVaUgguHynMJXhaEpt3rgZWx"
  },
  "result": "Error",
  "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
  "tokenTypes": [],
  "applicationId": "mg81t20ajcsvaoo2h9i35"
}

From my package.json:


"dependencies": {
    "@logto/react": "^2.1.1",
},
"resolutions": {
    "@logto/browser": "2.1.1",
    "@logto/client": "2.2.2",
    "@logto/js": "2.1.2"
  }

Please let me know what else I need to provide.

Can you share your code or provide a minimal reproducible project?

vastamaki commented 1 year ago

I've noticed the same behavior happening with the application when it tries to refresh users' tokens. Do we have any solutions or improvements planned to address this?

charIeszhao commented 1 year ago

I've noticed the same behavior happening with the application when it tries to refresh users' tokens. Do we have any solutions or improvements planned to address this?

Can you provide some screenshots for trouble shooting?

charIeszhao commented 1 year ago

I still get the same error using @react/browser@2.1.1:

{
  "ip": "::ffff:172.18.0.1",
  "key": "ExchangeTokenBy.RefreshToken",
  "error": "{\"stack\":\"InvalidGrant: invalid_grant\\n    at refreshTokenHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/grants/refresh_token.js:73:11)\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async callTokenHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:70:7)\\n    at async allowedGrantTypeCheck (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:53:7)\\n    at async supportedGrantTypeCheck (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:45:7)\\n    at async stripGrantIrrelevantParams (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/actions/token.js:33:7)\\n    at async auth (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:257:9)\\n    at async loadClient (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:152:9)\\n    at async setWWWAuthenticateHeader (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/token_auth.js:43:11)\\n    at async selectiveBody (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/selective_body.js:49:5)\\n    at async noCache (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/no_cache.js:3:3)\\n    at async errorHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/error_handler.js:26:7)\\n    at async ensureSessionSave (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/helpers/initialize_app.js:52:7)\\n    at async contextEnsureOidc (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/context_ensure_oidc.js:4:5)\\n    at async file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/helpers/initialize_app.js:222:5\\n    at async errorHandler (file:///etc/logto/node_modules/.pnpm/oidc-provider@8.2.2/node_modules/oidc-provider/lib/shared/error_handler.js:26:7)\",\"message\":\"invalid_grant\",\"allow_redirect\":true,\"name\":\"InvalidGrant\",\"error\":\"invalid_grant\",\"status\":400,\"statusCode\":400,\"expose\":true,\"error_description\":\"grant request is invalid\",\"error_detail\":\"grant not found\"}",
  "params": {
    "resource": "https://api.xxx.com",
    "client_id": "mg81t20ajcsvaoo2h9i35",
    "grant_type": "refresh_token",
    "refresh_token": "yVRCJXJRwM4YLOq02WmUVaUgguHynMJXhaEpt3rgZWx"
  },
  "result": "Error",
  "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
  "tokenTypes": [],
  "applicationId": "mg81t20ajcsvaoo2h9i35"
}

From my package.json:


"dependencies": {
    "@logto/react": "^2.1.1",
},
"resolutions": {
    "@logto/browser": "2.1.1",
    "@logto/client": "2.2.2",
    "@logto/js": "2.1.2"
  }

Please let me know what else I need to provide.

Some sample code to reproduce the issue would be appreciated.

vastamaki commented 1 year ago

I've noticed the same behavior happening with the application when it tries to refresh users' tokens. Do we have any solutions or improvements planned to address this?

Can you provide some screenshots for trouble shooting?

Sure, config and the request/response of the refresh attempt. Need anything else? I believe that config should be enough for the refresh flow to work but..? I hope the issue isn't between the chair and keyboard.

image image image

charIeszhao commented 1 year ago

I've noticed the same behavior happening with the application when it tries to refresh users' tokens. Do we have any solutions or improvements planned to address this?

Can you provide some screenshots for trouble shooting?

Sure, config and the request/response of the refresh attempt. Need anything else? I believe that config should be enough for the refresh flow to work but..? I hope the issue isn't between the chair and keyboard.

image image image

Thanks, but it would be better to show me the error details in Audit Logs, like some of them did above. Usually it will tell you the exact cause of your "Invalid grant" issue. Also, is there multiple "token" requests in your network panel? We have refresh token rotation enabled by default, so you can't use the same refresh token multiple times to acquire an access token.

It would also be helpful to show me where you called "getAccessToken" function in your code.

Btw, it would be more efficient if you can join our discord and ask your question there

vastamaki commented 1 year ago

Hmm, right... Most likely a user error. The error messages could be a bit more accurate tho, in case the invalid grant is related to an expired/used refresh token. Well thanks anyway, this definitely helps!

charIeszhao commented 1 year ago

Hmm, right... Most likely a user error. The error messages could be a bit more accurate tho, in case the invalid grant is related to an expired/used refresh token. Well thanks anyway, this definitely helps!

Well, not sure which case is yours but I'm glad it helps. Sounds like it was caused by a redundant token request, am I right?

waltcow commented 1 year ago

oidc/token request twice when React's StrictMode is enable,

which lead to

{"error":"invalid_grant","error_description":"grant request is invalid"}

fixed by modify packages/react/src/hooks/index.ts

  useEffect(() => {
    if (!logtoClient) {
    if (!logtoClient || isLoading || isAuthenticated) {
      return;
    }

@@ -95,7 +99,7 @@ const useHandleSignInCallback = (callback?: () => void) => {
        void handleSignInCallback(currentPageUrl);
      }
    })();
  }, [handleSignInCallback, isAuthenticated, logtoClient]);
  }, [handleSignInCallback, isLoading, isAuthenticated, logtoClient]);
wangsijie commented 1 year ago

@charIeszhao would you mind taking a look after the vacation?

charIeszhao commented 1 year ago

oidc/token request twice when React's StrictMode is enable,

which lead to

{"error":"invalid_grant","error_description":"grant request is invalid"}

fixed by modify packages/react/src/hooks/index.ts

  useEffect(() => {
    if (!logtoClient) {
    if (!logtoClient || isLoading || isAuthenticated) {
      return;
    }

@@ -95,7 +99,7 @@ const useHandleSignInCallback = (callback?: () => void) => {
        void handleSignInCallback(currentPageUrl);
      }
    })();
  }, [handleSignInCallback, isAuthenticated, logtoClient]);
  }, [handleSignInCallback, isLoading, isAuthenticated, logtoClient]);

Thanks for reporting. However, I think there could be a better solution without involving isLoading in this useEffect, as isLoading will change numerous times during the sign-in flow and thus it would unexpectedly trigger this useEffect block. IIRC, this has caused a bug in a previous version. I will try to find a better solution to work around this, however, due to the fact that this only affects the React strict mode, the priority will be lower than the other ongoing tasks. Will update this ticket once we have any update.

charIeszhao commented 1 year ago

Closing the issue due to inactivity for more than 30 days. Check the details in this blog post and see if it helps address your similar issues. Feel free to reopen if you think it is necessary. Thanks.