aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.41k stars 2.12k forks source link

Auth.currentSession does not refresh tokens automatically for some users specifically in android devices #13830

Open nerdifydev opened 1 day ago

nerdifydev commented 1 day ago

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

Authentication

Amplify Version

v5

Amplify Categories

auth

Backend

Amplify CLI

Environment information

``` # Put output below this line System: OS: macOS 14.6.1 CPU: (8) arm64 Apple M3 Memory: 67.95 MB / 16.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 22.6.0 - /opt/homebrew/bin/node Yarn: 1.22.22 - /opt/homebrew/bin/yarn npm: 10.8.2 - /opt/homebrew/bin/npm Watchman: 2024.08.26.00 - /opt/homebrew/bin/watchman Browsers: Chrome: 129.0.6668.58 Safari: 17.6 npmPackages: @babel/core: ^7.20.0 => 7.23.2 @babel/preset-env: ^7.20.0 => 7.23.2 @babel/runtime: ^7.20.0 => 7.23.2 @contentful/rich-text-react-renderer: ^15.22.1 => 15.22.11 @contentful/rich-text-types: ^16.6.1 => 16.8.5 @ekreative/react-native-braintree: ^2.4.0 => 2.4.0 @gorhom/bottom-sheet: ^4 => 4.5.1 @komo-tech/react-native-widgets: ^0.4.4 => 0.4.4 @react-native-async-storage/async-storage: ^1.19.3 => 1.19.4 @react-native-community/clipboard: ^1.5.1 => 1.5.1 @react-native-community/geolocation: ^3.1.0 => 3.1.0 @react-native-community/netinfo: ^11.2.1 => 11.3.2 @react-native-community/slider: ^4.5.0 => 4.5.0 @react-native-firebase/analytics: ^18.8.0 => 18.9.0 @react-native-firebase/app: ^18.8.0 => 18.9.0 @react-native-firebase/crashlytics: ^18.8.0 => 18.9.0 @react-native-firebase/remote-config: ^18.8.0 => 18.9.0 @react-native/eslint-config: ^0.74.86 => 0.74.87 @react-native/metro-config: ^0.72.11 => 0.72.11 @react-navigation/bottom-tabs: ^6.5.8 => 6.5.11 @react-navigation/material-top-tabs: ^6.6.3 => 6.6.5 @react-navigation/native: ^6.1.7 => 6.1.9 @react-navigation/native-stack: ^6.9.13 => 6.9.17 @rnw-community/react-native-payments: ^0.65.3 => 0.65.5 @sentry/react-native: 5.26.0 => 5.26.0 @splunk/otel-react-native: ^0.3.3 => 0.3.4 @storybook/addon-actions: ^6.5.16 => 6.5.16 @storybook/addon-controls: ^6.5.16 => 6.5.16 @storybook/addon-ondevice-actions: ^6.5.6 => 6.5.7 @storybook/addon-ondevice-controls: ^6.5.6 => 6.5.7 @storybook/addons: ^7.4.0 => 7.5.3 (6.5.16) @storybook/react-native: ^6.5.6 => 6.5.7 @storybook/theming: ^7.4.0 => 7.5.3 (6.5.16) @tap-payments/apple-pay-rn: ^0.1.3 => 0.1.3 @tsconfig/react-native: ^3.0.0 => 3.0.2 @twotalltotems/react-native-otp-input: ^1.3.11 => 1.3.11 @types/lodash: ^4.14.202 => 4.14.202 @types/react: ^18.0.24 => 18.2.37 @types/react-native-background-timer: ^2.0.2 => 2.0.2 @types/react-native-vector-icons: ^6.4.13 => 6.4.17 @types/react-test-renderer: ^18.0.0 => 18.0.6 @types/styled-components: ^5.1.26 => 5.1.30 @types/underscore: ^1.11.15 => 1.11.15 @types/uuid: ^9.0.6 => 9.0.7 HelloWorld: 0.0.1 amazon-cognito-identity-js: ^5.2.10 => 5.2.14 (6.3.7) amazon-cognito-identity-js/internals: undefined () awesome-phonenumber: ^5.10.0 => 5.11.0 aws-amplify: ^5.3.10 => 5.3.12 axios: ^1.5.0 => 1.6.1 (1.6.0) babel-jest: ^29.2.1 => 29.7.0 babel-loader: ^8.3.0 => 8.3.0 babel-plugin-dotenv-import: ^3.0.1 => 3.0.1 credit-card-type: ^10.0.0 => 10.0.0 eslint: ^8.19.0 => 8.53.0 example: 0.0.1 geolocationexample: 0.0.0 jest: ^29.2.1 => 29.7.0 lodash: ^4.17.21 => 4.17.21 metro-react-native-babel-preset: 0.76.8 => 0.76.8 (0.76.7, 0.76.9) mobx: ^6.9.0 => 6.10.2 mobx-react: ^8.0.0 => 8.0.0 mobx-react-lite: ^4.0.4 => 4.0.5 moment: ^2.29.4 => 2.29.4 moment-timezone: ^0.5.45 => 0.5.45 patch-package: ^8.0.0 => 8.0.0 postinstall-postinstall: ^2.1.0 => 2.1.0 prettier: ^2.4.1 => 2.8.8 react: 18.2.0 => 18.2.0 (18.3.1) react-dom: 18.2.0 => 18.2.0 react-native: 0.72.4 => 0.72.4 (0.72.17) react-native-android-location-enabler: ^2.0.1 => 2.0.1 react-native-animatable: ^1.3.3 => 1.4.0 react-native-apple-payment: ^1.2.0 => 1.2.0 react-native-asset: ^2.1.1 => 2.1.1 react-native-background-timer: ^2.4.1 => 2.4.1 react-native-bouncy-checkbox: ^3.0.7 => 3.0.7 react-native-circular-progress: ^1.3.9 => 1.3.9 react-native-code-push: ^8.2.2 => 8.3.1 react-native-config: ^1.5.1 => 1.5.1 (1.5.3) react-native-date-picker: ^4.3.5 => 4.3.5 react-native-device-info: ^10.12.0 => 10.14.0 react-native-dotenv: ^3.4.9 => 3.4.9 react-native-fast-image: ^8.6.3 => 8.6.3 react-native-fbsdk-next: ^12.1.4 => 12.2.0 react-native-forter: git+https://bitbucket.org/forter-mobile/forter-react-plugin.git => 1.0.2 react-native-geolocation: ^1.0.0 => 1.0.0 react-native-gesture-handler: ^2.12.1 => 2.13.4 react-native-get-random-values: ^1.9.0 => 1.9.0 react-native-google-pay: ^2.1.0 => 2.1.0 react-native-google-pay-button: ^0.2.0 => 0.2.0 react-native-google-places-autocomplete: ^2.5.5 => 2.5.6 react-native-keyboard-aware-scroll-view: ^0.9.5 => 0.9.5 react-native-maps: 1.15.4 => 1.15.4 react-native-markdown-display: ^7.0.2 => 7.0.2 react-native-marketingcloudsdk: 7.5.0 => 7.5.0 react-native-otp-verify: ^1.1.8 => 1.1.8 react-native-pager-view: ^6.2.1 => 6.2.2 react-native-permissions: ^4.0.1 => 4.0.1 react-native-progress: ^5.0.1 => 5.0.1 react-native-public-ip: ^1.0.2 => 1.0.2 react-native-qrcode-svg: ^6.3.0 => undefined (6.3.2, ) react-native-reanimated: ^3.5.1 => 3.5.4 react-native-reanimated-carousel: ^3.5.1 => 3.5.1 react-native-responsive-dimensions: ^3.1.1 => 3.1.1 react-native-safe-area-context: ^4.7.1 => 4.7.4 react-native-screens: ^3.25.0 => 3.27.0 react-native-share: ^9.4.1 => 9.4.1 react-native-slider: ^0.11.0 => 0.11.0 react-native-splash-screen: ^3.3.0 => 3.3.0 react-native-storybook-loader: ^2.0.5 => 2.0.5 react-native-svg: ^14.1.0 => 14.1.0 react-native-switch: ^1.5.1 => 1.5.1 react-native-tab-view: ^3.5.2 => 3.5.2 react-native-toast-message: ^2.1.7 => 2.1.7 react-native-tracking-transparency: ^0.1.2 => 0.1.2 react-native-vector-icons: 9.2.0 => 9.2.0 react-native-version-info: ^1.1.1 => 1.1.1 react-native-walkthrough-tooltip: ^1.5.0 => 1.5.0 react-native-webview: ^13.6.2 => 13.6.2 react-native-zigzag-view: ^0.2.0 => 0.2.0 react-test-renderer: 18.2.0 => 18.2.0 styled-components: ^5.3.9 => 5.3.11 styled-components/macro: undefined () styled-components/native: undefined () styled-components/primitives: undefined () typescript: 4.8.4 => 4.8.4 underscore: ^1.13.6 => 1.13.6 uuid: ^9.0.1 => 9.0.1 (3.4.0, 8.3.2, 7.0.3) ```

Describe the bug

Auth.currentSession is not refreshing tokens automatically for some users, specifically on Android devices. I spent a lot of time debugging it, but I was never able to reproduce the issue, even when going offline for a while and coming back online to receive a new token before the token expiration. The issue seems somewhat unreliable, as I checked a few Android devices where the token was refreshing seamlessly. It throws an error in the catch block of Auth.currentSession. I'm not sure if there's a way to force a token refresh in Auth.currentSession with AWS Amplify v5 for React Native.

Also, I do not store tokens locally in the app and makes every time call to Auth.currentSession to fetch the latest token.

Expected behavior

Auth.currentSession should automatically refresh the token when it expires and should not throw an error in catch block of Auth.currentSession.

Reproduction steps

Note: The issue is not consistently reproducible, making it challenging to debug.

Code Snippet

async getCurrentSession(): Promise<CognitoUserSession | void> {
    try {
      const session = await Auth.currentSession();
      return session;
    } catch (error) {
      CommonStore.setMessageTitle("Session Expired");
      CommonStore.setMessageSubtitle("Your session has expired. Please log in again.");
      // doing auto logout 
      this.logout()
      return;
    }
  }

Log output

``` // Put your logs below this line ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

ashishsoniDotsquares commented 1 day ago

I am also facing the same issue.

haverchuck commented 1 day ago

@ashishsoniDotsquares Are you also on Amplify JS version 5.x?

HuiSF commented 1 day ago

Hi @nerdifydev, thanks for providing the details.

It throws an error in the catch block of Auth.currentSession.

Do you have any details of the caught error, such as the message and error name it contained?

Also regarding to this detail:

Also, I do not store tokens locally in the app and makes every time call to Auth.currentSession to fetch the latest token

Can you elaborate? Do you mean you are preventing Amplify library from storing the auth token in the underlying AsyncStorage? Or do you mean you don't keep a reference to the object returned by a successful call of Auth.currentSession()?

nerdifydev commented 1 day ago

Hi @HuiSF, It says something like error - network error. It is something weird as users have proper network connectivity and it happens only when token expires.

The token expires but does not renew, so for now, I had to set the ID token expiration to 24 hours and the refresh token to more than a month.

HuiSF commented 1 day ago

Thanks for the addition details @nerdifydev, also and @ashishsoniDotsquares do you get the same error when this issue happened?

Could you both determine, did this happen at a occasion, for example, when the end users reopened the Android app from background? Also are you able to collect details of the Android devices that encountered this issue, such as Android OS version, device type etc.?

nerdifydev commented 1 day ago

Hi @HuiSF, I wanted to just add another point that I always fetch the latest token from Auth.currentSession.

Can you elaborate? Do you mean you are preventing Amplify library from storing the auth token in the underlying AsyncStorage? Or do you mean you don't keep a reference to the object returned by a successful call of Auth.currentSession()?

HuiSF commented 1 day ago

Sorry about the segmented requests @nerdifydev could you also confirm, after the error Network error happened, was the end user able to continue using the app, e.g. re-signing in, and did other Auth functionalities work?

ashishsoniDotsquares commented 1 day ago

@HuiSF @haverchuck, I'm on version 5.3 and encountering a similar error where the token expires but does not refresh, causing the error to be caught in the catch block. This is somewhat unreliable, as I am seeing unauthorized requests from users on both older and the latest Android OS versions (10 to 14), across various devices (Samsung, Pixel, Moto, etc.).

Are you also on Amplify JS version 5.x?

Unfortunately, I don't have any specific data on whether this happens on particular occasions.

do you get the same error when this issue happened? Could you both determine, did this happen at a occasion, for example, when the end users reopened the Android app from background? Also are you able to collect details of the Android devices that encountered this issue, such as Android OS version, device type etc.?

nerdifydev commented 1 day ago

Hi @HuiSF, Regarding to this detail:

@nerdifydev could you also confirm, after the error Network error happened, was the end user able to continue using the app, e.g. re-signing in, and did other Auth functionalities work?

Yes, as per the current functionality, we log users out of the app if an error occurs in Auth.currentSession, requiring them to sign in again. Upon re-signing, users receive a new token, so the error doesn't occur initially. However, when the token expires, Auth.currentSession is unable to renew it, and the cycle repeats.