oidc-client icon indicating copy to clipboard operation
oidc-client copied to clipboard

Multiple tabs - call to the same auth endpoint which throws an error.

Open pr0xyMity opened this issue 1 year ago • 11 comments

Issue and Steps to Reproduce

Hello, we came upon an issue with the request timing.

Our setup: We are using a provider that gives us the access_token and the refresh_token. The most important thing -> the refresh_token could be used only once. If it is used again the auth provider throws a 400 error.

The problem: We have our app in multiple tabs. Lets say 4 tabs. The first tab is doing a request and 3 other take the response by service worker. But sometimes after running for random amount of time 19m or 2h the app sends 2 requests form two different tabs. The one tab succeeds with 200 but the other have a 400. So the session lost is immediately shown on the second tab. The timing on the requests is the same.

Is there a way to specify that only one tab could do the requests? Maybe using https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API?

Versions

7.7.2

Screenshots

The screenshots are from two different tabs in the same window.

Screenshot 2023-10-31 at 13 06 25

Screenshot 2023-10-31 at 13 06 18

Expected

We only do request from on tab. Never from more than one.

Actual

Sometimes there are two request with the same refresh_token and the app says session lost.

pr0xyMity avatar Oct 31 '23 15:10 pr0xyMity

hi @pr0xyMity , thank you for your issue. It should have taken a long time to understand what happened. It is very interessting. Previously I have added a random number of time for each tabs.

I did not know about lock request. it look like it will be a good solution for resolve that issue. I'am in holiday this week. I may be able to fix it more onto the next week.

guillaume-chervet avatar Oct 31 '23 20:10 guillaume-chervet

hi @guillaume-chervet we have seen the random number in the code.

Firstly we assume that this will help, but sometimes if you have more tabs you can hit the exact same time for some tabs which leads to this error.

Maybe there should be an option that only one tab (maybe the first one open, the last one or even random) could do the authorization requests. If one tab out of bunch will have this leader flag this error would not appear never for n tabs.

Thank you for your response, enjoy the holiday!

pr0xyMity avatar Nov 01 '23 07:11 pr0xyMity

It seem related to this issue too #1055 Thank to @nicolas-goudry , i have a working example and thank to you @pr0xyMity , we have may be a solution ^^

guillaume-chervet avatar Nov 12 '23 14:11 guillaume-chervet

Hi! Just wanted to let you know that we have the same issue. It was partially fixed, as @guillaume-chervet mentioned in https://github.com/AxaFrance/oidc-client/issues/1039 by subtracting a random number from refresh_time_before_tokens_expiration_in_second. However, the issue still occurs sometimes, especially when many tabs are opened simultaneously. It would be great to have it solved and solution with Web Locks API looks very promising.

krzempekk avatar Nov 16 '23 11:11 krzempekk

Thank byou @krzempekk for your feedback. It is one of my priotity. I am pretty sure many issue come from this problem.

guillaume-chervet avatar Nov 16 '23 11:11 guillaume-chervet

I have make a mistake and push directly to main :/ (I thougth I was on a branch) version 7.9.3-alpha.1131 published start resolve the problem but it is not perfect.

guillaume-chervet avatar Nov 17 '23 16:11 guillaume-chervet

I hit the same bug myself. To reproduce, I configured the OIDC server to issue tokens valid for 30 seconds, and I specified refresh_time_before_tokens_expiration_in_second to be 15 seconds. I am using version 7.13.7 of @axa-fr/react-oidc.

I've attached a screen recording played back at 4x speed, showing what happens across two tabs.

If the left tab is Tab1 and the right tab is Tab2, then the sequence of events are:

  • Time 0: Tab2 refresh tokens successfully
  • Time 15: Tab1 refresh tokens successfully
  • Time 30: Tab2 refresh tokens successfully
  • Time 30+: Tab1 fails to refresh as it reuses the same refresh token as Tab2, which was just consumed.

Looking at this line: https://github.com/AxaFrance/oidc-client/blob/6667eabc8c5cb0ff5874b6583b2223721bd18525/packages/oidc-client/src/renewTokens.ts#L42 , should we specify ifAvailable: true here?

It seems like both tabs try to acquire a lock simultaneously, where Tab2 acquires it first, and Tab1 gets queued, and when Tab2 completes, Tab1 refreshes but with the old refresh token. There shouldn't be a need for Tab1 to refresh as long as the tab gets a copy of the new tokens when Tab2 finishes. Therefore, ifAvailable: true makes sense to me.

What do you think @guillaume-chervet?

https://github.com/AxaFrance/oidc-client/assets/4549941/e9a005e3-063c-42e1-8ec1-7eebe353efab

BugGambit avatar Dec 16 '23 11:12 BugGambit

Hi @BugGambit , I will set it back temporary, but i will need more work and to clean some code to make it works properly. I am lacking of time these days :(

guillaume-chervet avatar Dec 17 '23 15:12 guillaume-chervet

Hi @BugGambit i published back few days ago a better fix that sould work.

I need to clean that part.

guillaume-chervet avatar Dec 23 '23 14:12 guillaume-chervet

@guillaume-chervet I tested the new version, and it works like a charm 💯 Thanks for fixing this.

BugGambit avatar Jan 02 '24 12:01 BugGambit

Thank you for the feedback @BugGambit :)

I still need to clean deeper all this renew part.

guillaume-chervet avatar Jan 02 '24 13:01 guillaume-chervet