Skip to content

Fix App Check timer issues #6617

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 21, 2022
Merged

Fix App Check timer issues #6617

merged 6 commits into from
Sep 21, 2022

Conversation

hsubox76
Copy link
Contributor

@hsubox76 hsubox76 commented Sep 20, 2022

Fixes #6373

Causes

Found 2 causes of the problems:

  1. getToken() needs to return an error result (a dummy token with an error property) whenever there is an error. It was assuming that if there was an error there would be no token. This is not always the case. If the token is about to expire, the proactive refresh attempt may run into an error at the exchange endpoint. Then there will be an existing valid token, but also en error.
  2. When getToken() makes a request to the exchange endpoint, it stores the promise in state.exchangeTokenPromise and doesn't make another request if the promise is in flight, instead, any calls during that period await the existing promise. Once the promise is resolved, it clears state.exchangeTokenPromise, allowing future exchange requests to be made when needed. The mistake was that it only cleared this when the promise was resolved, and not when the promise was rejected, so that once an exchange request promise failed, another one wouldn't be made until memory was cleared. (This may be why users had to refresh the page.)

Solutions

  1. We need getToken() to return a token with a special error property, internalError. The reason this needs to be different from error, is that there's 2 different places that look for the error property on the result returned by getToken(). The first is the Refresher operation callback (defined inside createTokenRefresher), where we need it to find the error property (indicating there was an exchange request error) and throw, which will cause the Refresher to go into backoff retry mode. However, the other place that looks at error is notifyTokenListeners which calls the error callback for any 3P listeners if it finds error. If we have a valid token still, and it's just the proactive refresh attempt that's failing, we should just keep sending the token to 3P listeners as usual, it isn't an error from their point of view. That's why we use internalError for this case, so notifyTokenListeners can ignore it and the Refresher's operation callback can use it and throw, just as it does for error.
  2. Replaced then with finally. The return token part of the then callback is no longer needed as the original promise already returns the token.

Testing

Tested this using a 30 minute token and taking the tab offline using devtools, after initial token fetch. While offline, the app attempted to make requests to Firestore, and later App Check, after the App Check token had expired, but no more than 1 request per minute (and I think most were triggered by Firestore, which needs to get an App Check token when it tries to connect to the backend). After returning tab to online state, it immediately got a new token, and Firestore was able to write.

@changeset-bot
Copy link

changeset-bot bot commented Sep 20, 2022

🦋 Changeset detected

Latest commit: 15a0524

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@firebase/app-check Patch
@firebase/app-check-compat Patch
firebase Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Sep 20, 2022

Size Report 1

Affected Products

  • @firebase/app-check

    TypeBase (e35db6f)Merge (7f0de3a)Diff
    browser25.2 kB25.6 kB+336 B (+1.3%)
    esm529.9 kB30.3 kB+411 B (+1.4%)
    main31.1 kB31.5 kB+423 B (+1.4%)
    module25.2 kB25.6 kB+336 B (+1.3%)
  • bundle

    TypeBase (e35db6f)Merge (7f0de3a)Diff
    app-check (CustomProvider)35.5 kB35.7 kB+217 B (+0.6%)
    app-check (ReCaptchaEnterpriseProvider)37.7 kB37.9 kB+217 B (+0.6%)
    app-check (ReCaptchaV3Provider)37.7 kB37.9 kB+217 B (+0.6%)
  • firebase

    TypeBase (e35db6f)Merge (7f0de3a)Diff
    firebase-app-check-compat.js22.9 kB23.1 kB+197 B (+0.9%)
    firebase-app-check.js21.7 kB21.8 kB+175 B (+0.8%)
    firebase-compat.js738 kB738 kB+199 B (+0.0%)

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/N6rbXAaT7r.html

@google-oss-bot
Copy link
Contributor

Size Analysis Report 1

Affected Products

  • @firebase/app-check

    • CustomProvider

      Size

      TypeBase (e35db6f)Merge (e8a727d)Diff
      size7.51 kB7.59 kB+81 B (+1.1%)
      size-with-ext-deps25.0 kB25.0 kB+83 B (+0.3%)
    • ReCaptchaEnterpriseProvider

      Size

      TypeBase (e35db6f)Merge (e8a727d)Diff
      size11.1 kB11.1 kB+81 B (+0.7%)
      size-with-ext-deps28.4 kB28.5 kB+83 B (+0.3%)
    • ReCaptchaV3Provider

      Size

      TypeBase (e35db6f)Merge (e8a727d)Diff
      size11.0 kB11.1 kB+81 B (+0.7%)
      size-with-ext-deps28.4 kB28.4 kB+83 B (+0.3%)
    • getToken

      Size

      TypeBase (e35db6f)Merge (e8a727d)Diff
      size7.13 kB7.22 kB+81 B (+1.1%)
      size-with-ext-deps24.1 kB24.2 kB+83 B (+0.3%)
    • initializeAppCheck

      Size

      TypeBase (e35db6f)Merge (e8a727d)Diff
      size11.0 kB11.1 kB+77 B (+0.7%)
      size-with-ext-deps28.6 kB28.7 kB+78 B (+0.3%)
    • onTokenChanged

      Size

      TypeBase (e35db6f)Merge (e8a727d)Diff
      size7.23 kB7.31 kB+81 B (+1.1%)
      size-with-ext-deps24.2 kB24.3 kB+83 B (+0.3%)
    • setTokenAutoRefreshEnabled

      Size

      TypeBase (e35db6f)Merge (e8a727d)Diff
      size7.26 kB7.34 kB+81 B (+1.1%)
      size-with-ext-deps24.3 kB24.4 kB+83 B (+0.3%)

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/ODojxAu9mO.html

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Sep 20, 2022

Size Analysis Report 1

Affected Products

  • @firebase/app-check

    • CustomProvider

      Size

      TypeBase (e35db6f)Merge (7f0de3a)Diff
      size7.51 kB7.72 kB+217 B (+2.9%)
      size-with-ext-deps25.0 kB25.2 kB+222 B (+0.9%)
    • ReCaptchaEnterpriseProvider

      Size

      TypeBase (e35db6f)Merge (7f0de3a)Diff
      size11.1 kB11.3 kB+217 B (+2.0%)
      size-with-ext-deps28.4 kB28.6 kB+222 B (+0.8%)
    • ReCaptchaV3Provider

      Size

      TypeBase (e35db6f)Merge (7f0de3a)Diff
      size11.0 kB11.2 kB+217 B (+2.0%)
      size-with-ext-deps28.4 kB28.6 kB+222 B (+0.8%)
    • getToken

      Size

      TypeBase (e35db6f)Merge (7f0de3a)Diff
      size7.13 kB7.35 kB+217 B (+3.0%)
      size-with-ext-deps24.1 kB24.4 kB+222 B (+0.9%)
    • initializeAppCheck

      Size

      TypeBase (e35db6f)Merge (7f0de3a)Diff
      size11.0 kB11.2 kB+215 B (+2.0%)
      size-with-ext-deps28.6 kB28.8 kB+217 B (+0.8%)
    • onTokenChanged

      Size

      TypeBase (e35db6f)Merge (7f0de3a)Diff
      size7.23 kB7.45 kB+217 B (+3.0%)
      size-with-ext-deps24.2 kB24.5 kB+222 B (+0.9%)
    • setTokenAutoRefreshEnabled

      Size

      TypeBase (e35db6f)Merge (7f0de3a)Diff
      size7.26 kB7.48 kB+217 B (+3.0%)
      size-with-ext-deps24.3 kB24.5 kB+222 B (+0.9%)

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/9bt6fUnek8.html

@hsubox76 hsubox76 marked this pull request as ready for review September 20, 2022 21:56
@hsubox76 hsubox76 requested a review from egilmorez as a code owner September 20, 2022 21:56
Copy link
Contributor

@dwyfrequency dwyfrequency left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!! Everything looks good to me here

@hsubox76 hsubox76 merged commit b3951c6 into master Sep 21, 2022
@hsubox76 hsubox76 deleted the ch-ac-loopfix branch September 21, 2022 18:55
@digibake
Copy link

Hi @hsubox76

Do you know if this fix has been published yet? I'm currently running into mega infinite loop App Check problems (we're getting 90K invalid requests constantly every single hour for the last 7 days) and I think this may go a long way to fix them. We're really keen to update and try this fix as soon as possible.

Thanks for all the hard work

bhparijat pushed a commit that referenced this pull request Sep 23, 2022
@google-oss-bot google-oss-bot mentioned this pull request Sep 29, 2022
@firebase firebase locked and limited conversation to collaborators Oct 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
4 participants