amplify-js icon indicating copy to clipboard operation
amplify-js copied to clipboard

When using withAuthenticator, users are sometimes logged out when opening the app while offline

Open duckbytes opened this issue 2 years ago • 18 comments

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

Authentication, DataStore

Amplify Categories

auth

Environment information

  System:
    OS: Linux 5.18 Arch Linux
    CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor
    Memory: 6.91 GB / 31.26 GB
    Container: Yes
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 16.13.2 - ~/.nvm/versions/node/v16.13.2/bin/node
    Yarn: 1.22.19 - /usr/bin/yarn
    npm: 8.1.2 - ~/.nvm/versions/node/v16.13.2/bin/npm
  Browsers:
    Firefox: 106.0.2
  npmPackages:
    @aws-amplify/ui-react: ^3.5.9 => 3.5.9
    @aws-amplify/ui-react-internal:  undefined ()
    @aws-amplify/ui-react-legacy:  undefined ()
    @testing-library/jest-dom: ^5.16.5 => 5.16.5
    @testing-library/react: ^13.4.0 => 13.4.0
    @testing-library/user-event: ^13.5.0 => 13.5.0
    react: ^18.2.0 => 18.2.0 (18.1.0)
    react-dom: ^18.2.0 => 18.2.0
    react-scripts: 5.0.1 => 5.0.1
    web-vitals: ^2.1.4 => 2.1.4
    workbox-background-sync: ^6.5.4 => 6.5.4
    workbox-broadcast-update: ^6.5.4 => 6.5.4
    workbox-cacheable-response: ^6.5.4 => 6.5.4
    workbox-core: ^6.5.4 => 6.5.4
    workbox-expiration: ^6.5.4 => 6.5.4
    workbox-google-analytics: ^6.5.4 => 6.5.4
    workbox-navigation-preload: ^6.5.4 => 6.5.4
    workbox-precaching: ^6.5.4 => 6.5.4
    workbox-range-requests: ^6.5.4 => 6.5.4
    workbox-routing: ^6.5.4 => 6.5.4
    workbox-strategies: ^6.5.4 => 6.5.4
    workbox-streams: ^6.5.4 => 6.5.4
  npmGlobalPackages:
    @aws-amplify/cli: 10.4.0
    @ionic/cli: 6.20.3
    cordova: 11.0.0
    corepack: 0.10.0
    create-react-native-app: 3.8.0
    deadfile: 2.0.1
    native-run: 1.7.1
    npm: 8.1.2
    react-js-to-ts: 1.4.0
    ts-node: 10.9.1
    typescript: 4.8.2


Describe the bug

If a React app is registered with a service worker and the app is opened while offline the page will still load.

When using withAuthenticator to manage logins, the user is sometimes logged out and unable to access any offline data.

When used with DataStore this means that users are unable to access data stored locally on their device while offline.

Expected behavior

The user should be kept logged in when the app is opened while offline.

Reproduction steps

npx create-react-app auth-issue --template cra-template-pwa
cd auth-issue
npm install aws-amplify
npm install @aws-amplify/ui-react
amplify init # use defaults
amplify add auth # use defaults
amplify add hosting # use defaults
amplify publish

amplify auth console

Add a test user to Cognito.

Load the example up on Chrome on mobile and click the 3 dots at the top right > Install app Go offline by enabling airplane mode. Close the app fully. Reopen the app. The user may be logged out.

This seems more likely to happen if it is done some time after the app was last opened.

I haven't been able to recreate the issue on desktop yet.

Code Snippet

src/App.js

import React from "react";
import { withAuthenticator } from "@aws-amplify/ui-react";
import Amplify from "aws-amplify";

const config = require("../src/aws-exports");
Amplify.configure({
  ...config.default,
});

function App() {
  return <div>hello</div>;
}

export default withAuthenticator(App);

Log output

// Put your logs below this line


aws-exports.js

const awsmobile = {
    "aws_project_region": "eu-west-1",
    "aws_cognito_identity_pool_id": "eu-west-1:f675981e-9a3e-437b-9787-3a82a8b6e583",
    "aws_cognito_region": "eu-west-1",
    "aws_user_pools_id": "eu-west-1_22aenN7I6",
    "aws_user_pools_web_client_id": "41dfl18nl8t1o53b2ojb8626ed",
    "oauth": {},
    "aws_cognito_username_attributes": [],
    "aws_cognito_social_providers": [],
    "aws_cognito_signup_attributes": [
        "EMAIL"
    ],
    "aws_cognito_mfa_configuration": "OFF",
    "aws_cognito_mfa_types": [
        "SMS"
    ],
    "aws_cognito_password_protection_settings": {
        "passwordPolicyMinLength": 8,
        "passwordPolicyCharacters": []
    },
    "aws_cognito_verification_mechanisms": [
        "EMAIL"
    ]
};


export default awsmobile;

Manual configuration

No response

Additional configuration

No response

Mobile Device

Xiaomi Mi 9T

Mobile Operating System

Android 11

Mobile Browser

Chrome

Mobile Browser Version

106.0.5249.126

Additional information and screenshots

package.json

  "name": "auth-issue",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@aws-amplify/ui-react": "^3.5.10",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "aws-amplify": "^4.3.42",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4",
    "workbox-background-sync": "^6.5.4",
    "workbox-broadcast-update": "^6.5.4",
    "workbox-cacheable-response": "^6.5.4",
    "workbox-core": "^6.5.4",
    "workbox-expiration": "^6.5.4",
    "workbox-google-analytics": "^6.5.4",
    "workbox-navigation-preload": "^6.5.4",
    "workbox-precaching": "^6.5.4",
    "workbox-range-requests": "^6.5.4",
    "workbox-routing": "^6.5.4",
    "workbox-strategies": "^6.5.4",
    "workbox-streams": "^6.5.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "preserve:static": "npm run build",
    "serve:static": "npx serve ./build  -p 3000"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}```

duckbytes avatar Oct 31 '22 20:10 duckbytes

Another interesting thing is the app will become available again once a connection is restored:

  • close the app
  • enable airplane mode and open it which shows the login screen
  • close the app again
  • disable airplane mode
  • restart the app and get full access to the app again (without logging in)

duckbytes avatar Oct 31 '22 20:10 duckbytes

@duckbytes I tried to reproduce your issue. I used an Android emulator, 2 physical Android devices and an iPhone and the app is still logged in after I close the app every time. Is there anything else you are doing to get logged out? I am not being able to reproduce the issue

ncarvajalc avatar Nov 03 '22 18:11 ncarvajalc

Hi @ncarvajalc

Unfortunately it's quite difficult to reproduce because it seems to happen after a random length of time.

Sometimes I've opened the app in airplane mode a few minutes later and I've been logged out.

I tested it again today after your comment and had to wait a few hours before it logged me out. I tried at a few intervals before then, but it was still logged in.

The reason this effects my project more than most I think is because my users are doing deliveries in low signal areas. Sometimes they will log in to see a job, and then embark on an hour long trip to an area with no signal. Then on opening the app to update the job, they are logged out.

duckbytes avatar Nov 03 '22 23:11 duckbytes

I could actually visualize that random sign out this morning, a few hours had passed since log in. I'll take a deeper look into it.

ncarvajalc avatar Nov 04 '22 17:11 ncarvajalc

@duckbytes I could reproduce your issue successfully and now know the cause of the issue.

Reproduction steps

Same as yours + changing token expiration time in Cognito

amplify auth console
  • Select: ❯ User Pool

  • Go to App integration

  • Scroll down to App client list and select your app

  • Go to App client information and click the Edit button

  • Change the following settings: image

  • Quit the app in your phone after log in

  • Wait 5 minutes

  • Log in again

The user is now logged out.

When I quit the app and reestablish my internet connection the user has full access to the app again, without logging in.

I changed the expiration time of the tokens to 10 minutes and tried logging in after 5 minutes and still had access to the app. After 10 minutes I got logged out until I reestablished my internet connection. For your specific use case I would recommend tweaking your expiration times to your preference, at least enough for your delivery users to stay logged in during their trip.

I guess this is because the app checks for a valid token to access the entire app (which is renewed every time you log in or every time it tries to get a new valid token after it expires) and finds that the expiration time has passed, which leads the user to the reauthentication process.

ncarvajalc avatar Nov 04 '22 20:11 ncarvajalc

Oh that's great, thank you. I'll try it and see if it helps.

I was wondering if there is any way to configure this using the Amplify CLI and commit it to code? Or can it only be done manually?

duckbytes avatar Nov 05 '22 16:11 duckbytes

I think the only thing you can modify from the CLI is the refresh token duration (in days).

ncarvajalc avatar Nov 05 '22 17:11 ncarvajalc

In the docs you can see that is via amplify console auth

ncarvajalc avatar Nov 05 '22 17:11 ncarvajalc

Figured that was the case. I think I can close this as solved now.

Thanks for your help.

duckbytes avatar Nov 05 '22 17:11 duckbytes

Hello, I am seeing this has a 1 day limit while offline. Cognito does not let you update the token expiration time more than a day.

In my use case, I need to keep offline more than this... any ideas?

titiloxx avatar Nov 08 '22 15:11 titiloxx

@titiloxx any solution for this issue? I also need to keep the user offline more than a day.

aramiscubillo avatar Mar 06 '23 23:03 aramiscubillo

Unfortunately my users are reporting still being logged out of the app at random, even in areas of good signal.

Is there anything else I can try to help remedy this?

duckbytes avatar May 07 '23 14:05 duckbytes

Users who are being logged out often can't log back in either, receiving a "network error" message.

Often at the same time recently entered data is not properly being synced by DataStore. When the user is eventually able to log back in, their changes are undone.

A lot of this is negating the benefits of using DataStore at all, and data is being lost.

duckbytes avatar May 11 '23 20:05 duckbytes

Hello, @duckbytes. Wanted to follow up on this and see if there has been any recent reports of this still happening on either the latest versions of v5.X or v6+ of Amplify? Want to get this reviewed again internally if so.

cwomack avatar Dec 26 '23 23:12 cwomack

Hey @cwomack

I've not had any reports recently, but I'll send a message out to ask and see if anyone gets back to me.

duckbytes avatar Jan 05 '24 22:01 duckbytes

It seems like this is still happening. One user reported tonight that they were logged out and had to log in again while using native app on Android.

Here is the package.json for the mobile version:

{
    "name": "mobile",
    "version": "1.0.0",
    "main": "node_modules/expo/AppEntry.js",
    "scripts": {
        "start": "expo start",
        "android": "expo run:android",
        "ios": "expo run:ios",
        "web": "expo start --web",
        "test": "jest --watch --testTimeout=60000",
        "test:debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --testTimeout=100000000"
    },
    "dependencies": {
        "@aws-amplify/datastore-storage-adapter": "^2.0.42",
        "@aws-amplify/ui-react-native": "^1.2.20",
        "@azure/core-asynciterator-polyfill": "^1.0.2",
        "@expo/webpack-config": "^19.0.0",
        "@react-native-async-storage/async-storage": "1.18.2",
        "@react-native-community/netinfo": "9.3.10",
        "@react-native/gradle-plugin": "^0.72.11",
        "@react-navigation/bottom-tabs": "^6.5.8",
        "@react-navigation/material-bottom-tabs": "^6.2.16",
        "@react-navigation/native-stack": "^6.9.13",
        "@reduxjs/toolkit": "^1.9.5",
        "amazon-cognito-identity-js": "^6.3.1",
        "aws-amplify": "^5.3.11",
        "core-js": "^3.31.1",
        "expo": "^49.0.11",
        "expo-file-system": "~15.4.4",
        "expo-splash-screen": "~0.20.5",
        "expo-sqlite": "~11.3.3",
        "expo-status-bar": "~1.6.0",
        "faker": "5.5.3",
        "moment": "^2.29.4",
        "moment-timezone": "^0.5.43",
        "react": "18.2.0",
        "react-content-loader": "^6.2.1",
        "react-native": "0.72.6",
        "react-native-get-random-values": "~1.9.0",
        "react-native-paper": "^5.9.1",
        "react-native-paper-dates": "^0.18.12",
        "react-native-safe-area-context": "4.6.3",
        "react-native-screens": "~3.22.0",
        "react-native-svg": "13.9.0",
        "react-native-url-polyfill": "^2.0.0",
        "react-native-web": "~0.19.6",
        "react-redux": "^8.1.1",
        "redux-saga": "^1.2.3"
    },
    "devDependencies": {
        "@babel/core": "^7.20.0",
        "@testing-library/jest-native": "^5.4.2",
        "@testing-library/react-native": "^12.1.3",
        "@types/jest": "^29.5.3",
        "@types/react": "~18.2.14",
        "jest-expo": "^49.0.0",
        "mock-async-storage": "^2.2.0",
        "typescript": "^5.1.3"
    },
    "private": true,
    "description": "Mobile version of Platelet",
    "repository": {
        "type": "git",
        "url": "git+https://github.com/platelet-app/platelet-mobile.git"
    },
    "author": "Theo Cranmore",
    "license": "Apache-2.0",
    "bugs": {
        "url": "https://github.com/platelet-app/platelet-mobile/issues"
    },
    "homepage": "https://github.com/platelet-app/platelet-mobile#readme"
}

duckbytes avatar Jan 06 '24 20:01 duckbytes

We are running into a similar issue in our React app. We are not using Datastore.

Dependencies:

{
  ...
  "dependencies": {
    "@aws-amplify/ui": "5.9.0",
    "@aws-amplify/ui-react": "5.3.3",
    ...
    "aws-amplify": "5.3.15",
    ...
  },
  ...
}

We have implemented a network check prior to attempting a session refresh that looks at both the Browser's onLine flag, and makes a separate request to an unauthenticated endpoint. If either fail, then refreshSession() is never invoked. We never explicitly call signOut() at any point when the network is determined to be offline, yet there is still an automatic redirection to the login screen. This typically happens after waking a computer from sleep and returning to an app tab that was open the previous day. We think that the Authenticator component is automatically triggering this redirect to the login page under the hood.

Is this behavior expected when use withAuthenticator() or is there any way to prevent it?

Thank you!

astnmsn avatar Jan 30 '24 17:01 astnmsn

@astnmsn and @duckbytes, looking into this issue again and appreciate your patience on it. If this is still happening, have you been able to see if it's reproducible without using the withAuthenticator component (e.g. using only the Auth API's)?

And if it's still occurring, what version of Amplify are you using and have you tried it on latest? Appreciate any additional context/validation you can provide!

cwomack avatar Apr 30 '24 18:04 cwomack

Closing this issue out as we haven't heard back, but are also consolidating our efforts around improvements to offline session/token management into issue #10393. Feel free to upvote, comment, and leave additional context on that issue going forward.

cwomack avatar Jun 11 '24 16:06 cwomack