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.44k stars 2.13k forks source link

Auth.currentUserCredentials().identityId returns valid id when user is not authenticated #10990

Closed benjaminliang2 closed 1 year ago

benjaminliang2 commented 1 year ago

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

Authentication, REST API

Amplify Categories

auth

Environment information

``` # Put output below this line System: OS: Windows 10 10.0.19045 CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor Memory: 6.77 GB / 15.95 GB Binaries: Node: 16.13.1 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.19 - ~\AppData\Roaming\npm\yarn.CMD npm: 8.3.0 - C:\Program Files\nodejs\npm.CMD Browsers: Chrome: 110.0.5481.104 Edge: Spartan (44.19041.1266.0), Chromium (110.0.1587.46) Internet Explorer: 11.0.19041.1566 npmPackages: @babel/core: ^7.12.9 => 7.19.6 @react-native-async-storage/async-storage: ~1.17.3 => 1.17.11 @react-native-community/netinfo: ^9.3.7 => 9.3.7 @react-navigation/native: ^6.0.13 => 6.0.13 @react-navigation/native-stack: ^6.9.1 => 6.9.1 @react-navigation/stack: ^6.3.11 => 6.3.11 @reduxjs/toolkit: ^1.8.6 => 1.8.6 @reduxjs/toolkit-query: 1.0.0 @reduxjs/toolkit-query-react: 1.0.0 @types/jest: ^29.2.3 => 29.2.3 @types/node: ^18.11.10 => 18.11.10 @types/react: ^18.0.25 => 18.0.25 @types/react-dom: ^18.0.9 => 18.0.9 @types/react-native: ~0.69.1 => 0.69.15 HelloWorld: 0.0.1 amazon-cognito-identity-js: ^6.0.1 => 6.1.1 aws-amplify: ^5.0.7 => 5.0.7 expo: ~46.0.16 => 46.0.16 expo-app-loading: ~2.1.0 => 2.1.1 expo-checkbox: ~2.2.0 => 2.2.2 expo-font: ~10.2.0 => 10.2.1 expo-image-picker: ~13.3.1 => 13.3.1 expo-status-bar: ~1.4.0 => 1.4.0 hermes-inspector-msggen: 1.0.0 ini: ^1.3.5 => 1.3.8 inquirer: ^6.5.1 => 6.5.2 jest: ^26.6.3 => 26.6.3 jest-expo: ^47.0.1 => 47.0.1 react: 18.2.0 => 18.2.0 react-native: 0.69.6 => 0.69.6 react-native-circular-progress-indicator: ^4.4.0 => 4.4.0 react-native-gesture-handler: ^2.9.0 => 2.8.0 react-native-popup-menu: ^0.16.1 => 0.16.1 react-native-progress: ^5.0.0 => 5.0.0 react-native-reanimated: ^2.12.0 => 2.12.0 react-native-safe-area-context: 4.3.1 => 4.3.1 react-native-screens: ~3.15.0 => 3.15.0 react-native-svg: ^12.3.0 => 12.3.0 react-native-vector-icons: ^9.2.0 => 9.2.0 react-redux: ^8.0.4 => 8.0.4 react-test-renderer: ^18.2.0 => 18.2.0 (18.1.0) typescript: ^4.9.3 => 4.9.3 npmGlobalPackages: @aws-amplify/cli: 10.5.2 expo-cli: 6.0.6 heroku: 7.62.0 nodemon: 2.0.15 npm: 8.3.0 yarn: 1.22.19 ```

Describe the bug

Auth.currentUserCredentials().identityId returns a value such as "us-east-1:xxx......." even if there is no authenticated user.

Auth.currentAuthenticatedUser() seems to be working as it returns an error when the user is not authenticated.

Below is my code on app mount in react native

 useEffect(() => {
    loadApp();
  }, []);

  const loadApp = async () => {
    await Auth.currentAuthenticatedUser()
      .then((user) => console.log(user))
      .catch((err) => console.log("error signing in : ", err)); //executes as expected

    await Auth.currentUserCredentials()
      .then((cred) => console.log(cred)) //executes unexpectedly
      .catch((err) => console.log("error: " + err));
  };

Furthermore, if i signinuser1, call Auth.currentUserCredentials().identityId, signout user1, signin user2 call Auth.currentUserCredentials().identityId---the two values for two different users are the same. It seems that the credentials are not updated correctly.

Expected behavior

I expect Auth.currentUserCredentials()).identityId to return an error or null when there is no user signed in.

i expect Auth.currentUserCredentials()).identityId to return different values for different authenticated users.

Reproduction steps

Code Snippet

// Put your code below this line.
  useEffect(() => {
    loadApp();
  }, []);

  const loadApp = async () => {
    await Auth.currentAuthenticatedUser()
      .then((user) => {
        console.log(user)
      })
      .catch((err) => {
        console.log("error signing in : ", err);
      });
    await Auth.currentUserCredentials()
      .then((cred) => console.log(cred))
      .catch((err) => console.log("error: " + err));
  };

  const signUp = async () => {
      await Auth.signUp({
        username: email,
        password,
        attributes: {
          email, // optional
          name,
        },
        autoSignIn: {
          enabled: true
        },
        validationData: [], // optional
      })
        .then((data) => {
          console.log(data)
          Hub.listen('auth', listener) //to auto sign in user after sign up 
        })
        .catch((err) => {
          console.log(err);
        });

  };

  const signIn = async () => {
      await Auth.signIn(email, password)
        .then((user) => {
          console.log(user)
        })
        .catch((err) => {
           console.log(err)
          }
        });

  };

  const signOut = async () => {
    await Auth.signOut().catch((err) => {
      console.log(err);
    });
  };

Log output

``` // Put your logs below this line // output from `loadApp()` [15:01:12] error signing in : The user is not authenticated [15:01:12] Object { [15:01:12] "accessKeyId": "xxxxx", [15:01:12] "authenticated": false, [15:01:12] "expiration": 2023-02-17T02:01:13.000Z, [15:01:12] "identityId": "us-east-1:xxx-xxxx-xxxx-xxxx-xxxxxxx", [15:01:12] "secretAccessKey": "xxxxxxxxxx", [15:01:12] "sessionToken": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", [15:01:12] } ```

aws-exports.js

const awsmobile = {
    "aws_project_region": "us-east-1",
    "aws_dynamodb_all_tables_region": "us-east-1",
    "aws_dynamodb_table_schemas": [
        {
            "tableName": "table-dev",
            "region": "us-east-1"
        }
    ],
    "aws_cognito_identity_pool_id": "us-east-1:xxxx",
    "aws_cognito_region": "us-east-1",
    "aws_user_pools_id": "us-east-1_xxxx",
    "aws_user_pools_web_client_id": "xxxx",
    "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"
    ],
    "aws_cloud_logic_custom": [
        {
            "name": "nutritionAPI",
            "endpoint": "https://xxxx.us-east-1.amazonaws.com/dev",
            "region": "us-east-1"
        }
    ]
};

export default awsmobile;

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

tannerabread commented 1 year ago

Hi @benjaminliang2 do you know if you have unauthenticated/guest credentials allowed in your identity pool? If you do, currentUserCredentials will return something for the guest credentials when you are not logged in.

I tried this on a react native app created with the CLI and thought I was experiencing the same thing until I noticed the identityId when signed out was different from the signed in. I then checked the identity pool and found I had guest credentials enabled.

This also led me to see that the 2 different users I tried looked similar at first glance but were not. I will investigate this further if you can confirm those things about your app

tannerabread commented 1 year ago

Also, which device did you try this on? I tried on iOS emulator and a real iOS device. Someone else tried on web and we were not able to reproduce what you are seeing so far. Each user has their own unique identityId and guest users have a new, random identityId when signed out

benjaminliang2 commented 1 year ago

Hi @tannerabread, so I did have the "enable access to unauthenticated identities" checked, and i unchecked it. The behavior afterwards is somewhat expected but I still cant get the identityId So if I execute:

await Auth.currentUserCredentials()
      .then((cred) => console.log(cred))
      .catch((err) => console.log("error: " + err));

It behaves as expected, but i do not see a identityId property. I also tried console.log(cred.identityId) instead, but it just returns as "undefined".

I tried this on the web browser and my iPhone. I am using Expo Go for my phone. I start both with expo start

I also wanted to confirm my behavior when I still had "enable access to unauthenticated identities" checked. I double checked the data that's returned when calling

    await Auth.currentUserCredentials()
      .then((cred) => console.log(cred))
      .catch((err) => console.log("error: " + err));

I get something like

 Object {
[13:04:57]   "accessKeyId": "XXXXZNXXXJV5SFHXXXXX",
[13:04:57]   "authenticated": false,
[13:04:57]   "expiration": 2023-02-18T00:04:56.000Z,
[13:04:57]   "identityId": "us-east-1:c3f36508-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
[13:04:57]   "secretAccessKey": "XXXX",

Whether I am authenticated or not, the identityId and authenticated status is the same. Eveything else is different. There is also the sessionToken but I didnt check it as thats too long

tannerabread commented 1 year ago

That's some very interesting behavior. As no one has been able to reproduce this yet (after trying a few different apps/environments), would it be possible for you to provide a sample repo that demonstrates the behavior?

benjaminliang2 commented 1 year ago

I set up a different branch on my projects repo for this problem.

https://github.com/benjaminliang2/calorie-tracker-mobile/tree/debug

The auth logic is in the src/navigation folder, and

tannerabread commented 1 year ago

I tried with your repo and get the expected result where authenticated is false if I am not signed in, and the identityId is constant for my logged in user and different when I am logged out.

How were you checking the logged out behavior? From the branch "debug" that I cloned, logged out users only see the login screen, so I implemented a button on that screen to call the currentUserCredentials function and did the same on the main page for signed in users

benjaminliang2 commented 1 year ago

I am just using a try-catch block and console logging the result. I see the results in my gitbash terminal. In that case, I will try to implement this aws auth in a starter project. I am not sure whats happening with this current one.

tannerabread commented 1 year ago

Definitely let me know how that goes, I was wondering if maybe your resources got messed up somehow. Another route would be to take a clone of your own sample repo and try to amplify init some new resources and see if it works that way

benjaminliang2 commented 1 year ago

I was able to re-initialize amplify and auth seems to be working so far. I assume my resources got messed up as I did try to implement federated identities before I even verified basic authentication was working.

Right now, basic signin, signup, and signout are working with the expected identityId for unauth and authd users. Thank you for the help!!

tannerabread commented 1 year ago

Glad that worked! If you find that it happens again without touching your resources comment here so that we can figure out what happened.