FusionAuth/fusionauth-react-sdk

Token exchange endpoint getting called multiple times

Closed this issue · 5 comments

I am trying to recreate the example using a Vite/React app with a Serverless/Lambda REST API. I have the POST /token-exchange endpoint doing exactly as it does in the example server, and every time I try to login without an access_token cookie, it is calling the token-exchange endpoint twice. This causes it to error out since it's a race to whoever gets to claim the code first. Sometimes one call will succeed and the other will fail, other times both will fail. But never will both succeed (as they shouldn't). Not sure how much it helps as it's a very local setup, but here are the logs from my Docker container (note the first call succeeds and gives me a token and gets the user info, but the second call fails with an auth_code_not_found error):

fusionauth                     | 2022-12-16 08:43:27.606 PM WARN  org.elasticsearch.client.RestClient - request [PUT http://search:9200/fusionauth_user/_doc/cf82193b-56b6-4740-a75b-0bc1d8ee38fd] returned 1 warnings: [299 Elasticsearch-7.17.0-bee86328705acaa9a6daede7140defd4d9ec56bd "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html to enable security."]
forms-services                 |
forms-services                 |
forms-services                 | POST /token-exchange (λ: tokenExchange)
forms-services                 |
forms-services                 |
forms-services                 | POST /token-exchange (λ: tokenExchange)
forms-localstack               | 2022-12-16T20:43:32.845  INFO --- [   asgi_gw_0] localstack.request.aws     : AWS secretsmanager.GetSecretValue => 200
forms-services                 | user info ClientResponse {
forms-services                 |   statusCode: 200,
forms-services                 |   response: {
forms-services                 |     applicationId: <redacted>,
forms-services                 |     email: <redacted>,
forms-services                 |     email_verified: true,
forms-services                 |     family_name: 'Dura',
forms-services                 |     given_name: 'Josh',
forms-services                 |     roles: [],
forms-services                 |     scope: 'openid offline_access',
forms-services                 |     sid: <redacted>,
forms-services                 |     sub: <redacted>,
forms-services                 |     tid: <redacted>
forms-services                 |   }
forms-services                 | }
forms-services                 | (λ: tokenExchange) RequestId: 6f693574-2c1c-4879-b922-a1d1cf658d73  Duration: 5184.44 ms  Billed Duration: 5185 ms
forms-localstack               | 2022-12-16T20:43:33.032  INFO --- [   asgi_gw_2] localstack.request.aws     : AWS secretsmanager.GetSecretValue => 200
forms-services                 | error with oauth2/token endpoint call {"statusCode":400,"exception":{"error":"invalid_request","error_description":"Invalid Authorization Code","error_reason":"auth_code_not_found"}}
forms-services                 | (λ: tokenExchange) RequestId: 00c5005e-59f9-4a1e-a758-7a8c6b71945b  Duration: 5250.92 ms  Billed Duration: 5251 ms
forms-services                 | error Error: [object Object]
forms-services                 |     at /source/.build/utils/fusionauth.js:87:27
forms-services                 |     at step (/source/.build/utils/fusionauth.js:33:23)
forms-services                 |     at Object.throw (/source/.build/utils/fusionauth.js:14:53)
forms-services                 |     at rejected (/source/.build/utils/fusionauth.js:6:65)
forms-services                 |     at processTicksAndRejections (node:internal/process/task_queues:96:5)

@joshdura Thanks for the feedback. I asked the developer of the component about this behavior when I saw it and he said this:

This is a side effect of the way React 18 works when running using StrictMode in development mode. React 18 will mount, unmount, and remount all components in this mode, which results in the
network call running twice. This will not happen in a production build or if StrictMode is disabled. If you remove the `React.StrictMode` tags in `index.tsx` of the example app, you should see the
call is only made once.

Can you please try removing React.StrictMode if present and see if that helps?

If it doesn't, please let me know and we can try to recreate/fix.

If it is a fix, I need to document it.

Can you please try removing React.StrictMode if present and see if that helps?

If it doesn't, please let me know and we can try to recreate/fix.

Yup, that indeed fixed it. I do still get an issue of the user cookie being undefined after logout/login, but think that's part of another issue. Thanks for the quick reply!

okay, great. Please feel free to file another issue if needed. I'm going to leave this open until I document the fix.

Documented in deaa2fa