amplify-js: Cannot retrieve a new session. Please authenticate. [Auth + No AppSync]

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

Authentication

Amplify Categories

auth

Environment information

# Put output below this line
System:
    OS: macOS 13.1
    CPU: (8) arm64 Apple M1
    Memory: 1.02 GB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 19.3.0 - /opt/homebrew/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 9.2.0 - /opt/homebrew/bin/npm
    Watchman: 2022.12.12.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 111.0.5563.146
    Safari: 16.2
  npmPackages:
    @react-native-async-storage/async-storage: ^1.17.11 => 1.17.11 
    @react-native-community/netinfo: ^9.3.6 => 9.3.6 
    amazon-cognito-identity-js: ^5.2.12 => 5.2.12 
    aws-amplify: ^4.3.43 => 4.3.43 
    jwt-decode: ^3.1.2 => 3.1.2 
    react: 18.2.0 => 18.1.0 (16.14.0)
    react-native: 0.71.4 => 0.70.5 
  npmGlobalPackages:
    npm: 9.2.0

Describe the bug

Sometimes Auth.currentSession() throughs an error like “Cannot retrieve a new session. Please authenticate.”. For this kind of message, do I really need to re-authenticate anyhow? Like I logged in 7 days ago and my refresh token was going to expire on the 30th day of logging in. Can you please share in which situations this kind of error was raised?

Expected behavior

Auth.currentSession() should able to retrieve a new session if the old session failed due to any reason. Authentication of the user should not be required in this situation.

Reproduction steps

  1. Re-authenticate the user after logout.
  2. Close the application.
  3. Open the application.
  4. await Auth.currentSession() method gets called and throws an error with the message “Cannot retrieve a new session. Please authenticate.”.

Code Snippet

// Put your code below this line.

const AWSSessionHandler = async (): Promise<CognitoUserSession | void> => {
  return await Auth.currentSession().then(async data => {
    const updatedToken = data.getAccessToken().getJwtToken();
    await getAuthToken().then(
      async currentToken => currentToken !== updatedToken && (await setAuthToken(updatedToken))
    );
  });
};

await AWSSessionHandler()

Log output

// Put your logs below this line
Cannot retrieve a new session. Please authenticate.

aws-exports.js

No response

Manual configuration

{
  Auth: {
       region: AWS_REGION, // its confidential
       userPoolId: AWS_USERPOOLID, // its confidential
       userPoolWebClientId: AWS_USERPOOLWEBCLIENTID, // its confidential
       mandatorySignIn: false,
       authenticationFlowType: USER_PASSWORD_AUTH,
       storage: MyStorage, // Used react-native-keychain for secure storage instead of AsyncStorage.
  },
}

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

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 30 (10 by maintainers)

Most upvoted comments

@aliza-khu, apologies for the delayed response. I had tried to reproduce the issue you’re experiencing the Cannot retrieve a new session. Please authenticate error, but haven’t been able to yet. I just reviewed your comment again stating that “weak internet” may help in reproducing, so I’ll try throttling the network down to 3G speeds and see if I can reproduce. And you’re still not certain whether this happens on iOS or Android?

@its-aazizi, are you experiencing this on either iOS or Android specifically?

It reproduces when you replace the code of your custom storage with mine (https://github.com/aws-amplify/amplify-js/issues/11156#issuecomment-1491351128 - Not platform specific replicated on both the platforms) and try with a bad internet situation.

Note: Please call the API as soon as the app reaches the very first screen.

FireShot Capture 001 - Edit app client information } App client_ user-pool-client } amazon-l_ - ca-central-1 console aws amazon com

Here’s a screenshot for my app client settings, for testing purposes I’ve set the refresh token expiry to an hour, but the issue was still their when the refresh token expiry was set to 30 days, the user would unexpectedly loose the session in an hour or so and get logged out.

@cwomack I’m facing this on web.

Hello @cwomack, No reply since last week 😞. Please do reply at-least.

@aliza-khu, I was able to implement your custom storage solution that uses react-native-keychain in a React Native app and didn’t experience the issue. I don’t have any issues using AsyncStorage either (rather than custom storage solution w/ keychain). So far it seems like the next steps to determine what is causing this would be:

  1. Try temporarily swapping out the custom storage for the default AsyncStorage fixes the issue (just to isolate and verify if it’s being caused by the custom storage or something local tied to that).

  2. Time how long it is taking until you experience the error again (either by looking at logs or manually timing). I know you mentioned that it happens, “after some time” and that it happens very rarely… but maybe we can see if there’s a certain time it takes and dig deeper on the Cognito side to see why the session would be expired/invalid.

  3. Determine if this happens with Android, iOS, or both to see if there are related issues.

  4. Compare our package.json to see if there’s a dependency issue that might be causing this. This is what I’ve got and have tested locally, but can’t reproduce the issue:

// package.json dependencies 

  "dependencies": {
    "@aws-amplify/ui-react": "^4.6.0",
    "@react-native-async-storage/async-storage": "^1.18.1",
    "@react-native-community/masked-view": "^0.1.11",
    "@react-native-community/netinfo": "^9.3.9",
    "@react-navigation/native": "^6.1.6",
    "@react-navigation/stack": "^6.3.16",
    "amazon-cognito-identity-js": "^6.2.0",
    "aws-amplify": "^5.1.2",
    "core-js": "^3.30.1",
    "expo": "~48.0.11",
    "expo-status-bar": "~1.4.4",
    "react": "18.2.0",
    "react-native": "0.71.6",
    "react-native-gesture-handler": "^2.9.0",
    "react-native-keychain": "^8.1.1",
    "react-native-reanimated": "^3.0.2",
    "react-native-safe-area-context": "^4.5.1",
    "react-native-screens": "^3.20.0",
    "react-redux": "^8.0.5",
    "redux": "^4.2.1"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0"

@aliza-khu, appreciate your patience as I’m trying to reproduce and find a workaround that can be posted here either with a sample repo or code that utilizes a similar custom storage w/ react-native-keychain.

@cwomack, Here is the snap of custom storage which I think is the correct one.


static sync(): Promise<void> {
    if (!MyStorage.syncPromise) {
      MyStorage.syncPromise = new Promise<void>((res, rej) => {
        Keychain.getAllGenericPasswordServices()
          .then(keys => {
            const memoryKeys = keys.filter(function (key) {
              return key.startsWith(MEMORY_KEY_PREFIX);
            });

            if (memoryKeys.length === 0) {
              res();
            } else {
              memoryKeys.map((k, i) => {
                Keychain.getGenericPassword({
                  service: k,
                  securityLevel: Keychain.SECURITY_LEVEL.SECURE_SOFTWARE,
                })
                  .then(credentials => {
                    const updatedKey = k.replace(MEMORY_KEY_PREFIX, '');
                    dataMemory[updatedKey] = credentials ? credentials.password : {};
                    i === memoryKeys.length - 1 && res();
                  })
                  .catch(error => {
                    captureExcptionInSentryWithScope([], error);
                    rej(error);
                  });
              });
            }
          })
          .catch(err => {
            captureExcptionInSentryWithScope([], err);
            rej(err);
          });
      });
    }

    return MyStorage.syncPromise;
  }

You can compare this with previously shared custom storage snap.