question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Storage events can cause race conditions

See original GitHub issue

In the auth-service there is a storage event listener added. This might cause race conditions. For example:

  1. Tab A and Tab B both have the app open, not logged in yet
  2. Tab A logs in. Internally in auth-service from the library, a function will run that starts with setting the access_token in storage
  3. Tab B starts responding to that change before tab A completes with the function
  4. Tab B’s response is to load the user info, and upon response from the server the sub from the response is checked against the Identity Claims in storage, but Tab A never got to save that yet because it’s thread on the CPU didn’t get prio.
  5. Tab B will now throw an error because the sub from the user info endpoint doesn’t match null from storage.

So:

  • Workaround: wrap logic in setTimeout to make it very likely that Tab A handles everything before Tab B
  • Solution: don’t respond to storage events, but make tabs propagate OAuthEvents properly to sibling tabs

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:1
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
pegma-repocommented, Oct 1, 2020

@l1b3r I really like your solution. This way the service is not listening to every “access_code” change encountered. I found that extending the condition helps to avoid event firing again after _storage.removeItem() is called and adding an event.key null check helps cover localStorage.clear(). What do you guys think? My 2c.

    window.addEventListener('storage', (event) => {
      if ((event.key === 'auth_data_updated' && event.newValue !== null) || event.key === null) {
        console.log('Auth data has been updated in localStorage');
        this.isAuthenticatedSubject$.next(this.oauthService.hasValidAccessToken());

        if (!this.oauthService.hasValidAccessToken()) {
          this.navigateToLoginPage();
        }
      }
    });

PS: I used this with your storeAccessTokenResponse() override. Thank you for sharing! Edit: typos & ps

1reaction
jeroenheijmanscommented, Sep 14, 2020

Thx for the additional option @l1b3r! I’m leaving this issue open for now, it’s linked from the sample code too so others might want to use your solution for their apps! ❤️

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is a Race Condition? - TechTarget
Race conditions show up in several ways in software, storage, memory and networking. Proactively monitoring for them and preventing them is a critical...
Read more >
Best way to prevent race condition in multiple chrome.storage ...
If tasks can be dynamically produced as well as consumed, remember that race conditions will need to be prevented there as well but...
Read more >
How to Deal with Race Conditions - The New Stack
"Race conditions" refers to bugs that occur due to the timing or order-of-execution of multiple operations. Here's how to deal with them.
Read more >
Using JS and Storage to mitigate webhook race conditions
You want to pick a reference for the incoming event that can be used to identify duplicates (e.g., an external ID of some...
Read more >
Manifest V3 Question - Race Condition Prevention
There is no kind of "compare and swap" storage API or other kinds of locking/mutex facilities to make sure that data is not...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found