Skip to content
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

User authentication not persisted in browser: not authenticated #6555

Closed
janhesters opened this issue Aug 12, 2020 · 21 comments
Closed

User authentication not persisted in browser: not authenticated #6555

janhesters opened this issue Aug 12, 2020 · 21 comments
Labels
Auth Related to Auth components/category SSR Issues related to Server Side Rendering to-be-reproduced Used in order for Amplify to reproduce said issue

Comments

@janhesters
Copy link

janhesters commented Aug 12, 2020

Heads up
Opening this issue because all related issues seem to be closed WITHOUT an answer or solution for browsers, but many people face this problem.

Related issues:

Describe the bug

Authenticating the user in the browser and directly calling currentAuthenticatedUser results in an error. It looks like neither local storage nor cookie storage is being used to persist the session.

To Reproduce
Steps to reproduce the behavior:

  1. Run amplify init && amplify add auth in a project. Choose defaults.
  2. Configure Amplify in _app.js in a Next.js app. (BUT I also just reproduced this with a regular CRA app).
  3. Call Auth.signIn with valid credentials for a confirmed account. It returns a user correctly.
  4. Call Auth.currentAuthenticatedUser. It throws an error not authenticated.

If you set Amplify.Logger.LOG_LEVEL = 'DEBUG'; this is the output:

Screenshot 2020-08-12 at 19 59 24

Expected behavior

currentAuthenticatedUser should return the user correctly.

Code Snippet

// _app.js
import Auth from '@aws-amplify/auth';
import Amplify from '@aws-amplify/core';

import config from './aws-exports.js';

Amplify.configure(config);

// my-page.js
const signIn = async ({ email, password }) => await Auth.signIn(email, password);

async function refreshCurrentAuthenticatedUsersTokens() {
  const user = await Auth.currentAuthenticatedUser();
  console.log('user', user);
  const currentSession = user.signInUserSession;

  return new Promise((resolve, reject) => {
    user.refreshSession(currentSession.refreshToken, (error, data) => {
      if (error) {
        reject(error);
      }
      resolve(data);
    });
  });
}

async function handleClick() {
  try {
    const user = await signIn({ email: 'bob@foo.com', password: 'secret-stuff99' });
    console.log('user', user);
    const response = await refreshCurrentAuthenticatedUsersTokens();
    console.log('response', response);
  } catch (error) {
    console.log('error', error);
  }
}

Add this to a button's onClick handler and click it. You get an error: 'not authenticated'

What is Configured?

Only authentication as described above.

{
  "userPoolId": "eu-west-2_ikgbLyfwt",
  "userPoolWebClientId": "XXX",
  "region": "eu-west-2",
  "identityPoolId": "eu-west-2:XXX",
  "identityPoolRegion": "eu-west-2",
  "mandatorySignIn": false,
  "aws_project_region": "eu-west-2",
  "aws_cognito_identity_pool_id": "eu-west-2:XXX",
  "aws_cognito_region": "eu-west-2",
  "aws_user_pools_id": "eu-west-2_ikgbLyfwt",
  "aws_user_pools_web_client_id": "XXX",
  "oauth": {}
}
Environment
npx envinfo --system --binaries --browsers --npmPackages --npmGlobalPackages

  System:
    OS: macOS 10.15.6
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Memory: 398.82 MB / 32.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.16.1 - ~/.nvm/versions/node/v12.16.1/bin/node
    Yarn: 1.22.0 - ~/.yarn/bin/yarn
    npm: 6.14.4 - ~/.nvm/versions/node/v12.16.1/bin/npm
  Browsers:
    Brave Browser: 84.1.11.101
    Chrome: 84.0.4147.105
    Safari: 13.1.2
  npmPackages:
    @aws-amplify/auth: 3.3.3 => 3.3.3 
    @aws-amplify/core: 3.4.4 => 3.4.4 
    @babel/core: 7.10.5 => 7.10.5 
    @babel/node: 7.10.5 => 7.10.5 
    @redux-saga/testing-utils: 1.1.3 => 1.1.3 
    @reduxjs/toolkit: 1.4.0 => 1.4.0 
    babel-plugin-module-name-mapper: 1.2.0 => 1.2.0 
    babel-plugin-module-resolver: 4.0.0 => 4.0.0 
    babel-plugin-ramda: 2.0.0 => 2.0.0 
    classnames: 2.2.6 => 2.2.6 
    eslint: 7.5.0 => 7.5.0 
    eslint-config-prettier: 6.11.0 => 6.11.0 
    eslint-plugin-import: 2.22.0 => 2.22.0 
    eslint-plugin-jsx-a11y: 6.3.1 => 6.3.1 
    eslint-plugin-prettier: 3.1.4 => 3.1.4 
    eslint-plugin-react: 7.20.4 => 7.20.4 
    eslint-plugin-react-hooks: 4.0.8 => 4.0.8 
    eslint-plugin-simple-import-sort: 5.0.3 => 5.0.3 
    formik: 2.1.5 => 2.1.5 
    husky: 4.2.5 => 4.2.5 
    jsonwebtoken: 8.5.1 => 8.5.1 
    jwk-to-pem: 2.0.4 => 2.0.4 
    next: 9.5.1 => 9.5.1 
    prettier: 2.0.5 => 2.0.5 
    ramda: 0.27.1 => 0.27.1 
    react: 16.13.1 => 16.13.1 
    react-dom: 16.13.1 => 16.13.1 
    react-redux: 7.2.1 => 7.2.1 
    redux-logger: 3.0.6 => 3.0.6 
    redux-saga: 1.1.3 => 1.1.3 
    riteway: 6.1.2 => 6.1.2 
    tap-nirvana: 1.1.0 => 1.1.0 
    watch: 1.0.2 => 1.0.2 
    yup: 0.29.2 => 0.29.2 
  npmGlobalPackages:
    @ionic/cli: 6.2.1
    cordova-res: 0.10.0
    elm-format: 0.8.3
    elm-live: 4.0.2
    elm-test: 0.19.1-revision2
    native-run: 0.3.0
    now: 17.0.4
    npm: 6.14.4
@janhesters janhesters added the to-be-reproduced Used in order for Amplify to reproduce said issue label Aug 12, 2020
@janhesters
Copy link
Author

After some digging in the code, I found a likely explanation, which could help to prevent this bug in the future.

It looks like currentUser.setSignInUserSession(session); is only called when the config from aws-exports.js contains an oauth key. This calls cacheTokens under the hood, which sets the user into localStorage. This ain't happening when you call Auth.signIn for some reason. Feel like it should always happen, shouldn't it?

@janhesters
Copy link
Author

janhesters commented Aug 13, 2020

Another update: it looks like there is no session associated with the user. Maybe because I have MFA setup, but when I call Auth.signIn no MFA challenge is triggered 🤔 I neither get an Email nor an SMS ...

If I delete the user pool and recreate it with MFA turned off, the login works.

So my question is, what methods need to be called with MFA activated when doing the sign in manually?

@amhinson amhinson added the Auth Related to Auth components/category label Aug 17, 2020
@ericclemmons
Copy link
Contributor

@janhesters I just stood up a Next.js sample following your steps and was able to get things working successfully.

However, I noticed that after calling signUp and then signIn, I got an error indicated that the account hasn't been confirmed. Once I added in a call to Auth.confirmSignUp, both Auth.signIn and Auth.currentAuthenticatedUser worked as expected:

https://docs.amplify.aws/lib/auth/emailpassword/q/platform/js#confirm-sign-up

I'd recommend giving https://docs.amplify.aws/ui/auth/authenticator/q/framework/react a try to at least validate that the flow works successfully for you using <AmplifyAuthenticator>. (There may be some state transitions in the Auth flow you're missing)

https://docs.amplify.aws/ui/auth/authenticator/q/framework/react

When we ship #5435, we'll also include a Next.js sample here:

https://github.com/aws-amplify/amplify-js-samples

@janhesters
Copy link
Author

@ericclemmons Thanks for trying to reproduce it, but no, the account is confirmed. Will built this up from scratch again and comment further below.

We can't (or don't want to) use AmplifyAuthenticator because we want to control the authentication using sagas, which is why we rely on calling Auth manually.

@ericclemmons
Copy link
Contributor

@janhesters I understand not wanting to use AmplifyAuthenticator for the project, but I do recommend giving it a shot to see if the sign-in flow works with that pre-built component.

I'm hoping that'll tell is one of two things: whether the problem is with the client-side flow, or if there's a configuration/service problem.

@sureshungarala
Copy link

sureshungarala commented Sep 7, 2020

@ericclemmons @janhesters Had the same problem. Completing the flow with ui-react's withAuthenticator on first time solved for me.
In my case, user wasn't confirmed and I was trying with Auth.signIn API to signin user with temp pwd following which Auth.currentAuthenticatedUser API wasn't returning loggedIn user(cached/stored).

Would like to see this issue fixed with Auth.signIn rather than opting AmplifyAuthenticator with each new user.

Update: Calling Auth.completeNewPassword() after Auth.signIn() does solve this problem if signedIn with temp password initially.

@sammartinez sammartinez added the SSR Issues related to Server Side Rendering label Oct 1, 2020
@ericclemmons
Copy link
Contributor

@janhesters Have you been able to research this further? Based on this comment, I'm curious if the root cause is with the complexity of Auth flows (with temp tokens, validation, etc.):

#6555 (comment)

@paragbaxi
Copy link

paragbaxi commented Nov 4, 2020

Having the same issue, doesn't happen with withAuthenticator HOC. Problem is I cannot use the HOC as props do not get passed.

[DEBUG] 57:26.508 AuthClass - getting current authenticated user
[DEBUG] 57:26.508 AuthClass - get current authenticated userpool user
[DEBUG] 57:26.508 AuthClass - Failed to get user from user pool
[DEBUG] 57:26.508 AuthClass - The user is not authenticated by the error No current user

meanwhile this page serverside redirects upon no authentication to a withAuthenticator page. this page shows that user is, in fact, logged in.

logs:

[DEBUG] 00:17.987 Amplify - component registered in amplify AuthClass {userPool: null, user: null, oAuthFlowInProgress: false, Credentials: CredentialsClass, currentCredentials: ƒ, …}
ConsoleLogger.js?36de:97 [DEBUG] 00:18.86 AuthClass - configure Auth
ConsoleLogger.js?36de:107 [DEBUG] 00:18.86 Parser - parse config (3) [{…}, "to amplifyconfig", {…}]
ConsoleLogger.js?36de:107 [DEBUG] 00:18.89 Hub - Dispatching to auth with {event: "configured", data: null, message: "The Auth category has been configured successfully"}
ConsoleLogger.js?36de:107 [DEBUG] 00:18.90 Hub - Dispatching to auth with {event: "configured", data: null, message: "The Auth category has been configured successfully"}
ConsoleLogger.js?36de:107 [DEBUG] 00:18.91 AnalyticsClass - on hub capsule auth {event: "configured", data: null, message: "The Auth category has been configured successfully"}
ConsoleLogger.js?36de:107 [DEBUG] 00:18.91 Hub - Dispatching to auth with {event: "configured", data: null, message: "The Auth category has been configured successfully"}
ConsoleLogger.js?36de:97 [DEBUG] 00:18.145 AuthClass - getting current authenticated user
ConsoleLogger.js?36de:97 [DEBUG] 00:18.153 AuthClass - get current authenticated userpool user
ConsoleLogger.js?36de:97 [DEBUG] 00:18.178 AuthClass - getting current authenticated user
ConsoleLogger.js?36de:97 [DEBUG] 00:18.179 AuthClass - get current authenticated userpool user
profile.tsx?6ed7:15 User: CognitoUser {username: "paragbaxi", pool: CognitoUserPool, Session: null, client: Client, signInUserSession: CognitoUserSession, …}
ConsoleLogger.js?36de:97 [DEBUG] 00:18.521 AuthClass - getting current authenticated user
ConsoleLogger.js?36de:97 [DEBUG] 00:18.524 AuthClass - get current authenticated userpool user
ConsoleLogger.js?36de:107 [DEBUG] 00:18.531 Hub - Dispatching to UI Auth with {event: "AuthStateChange", message: "signedin", data: CognitoUser}
ConsoleLogger.js?36de:97 [DEBUG] 00:18.532 AuthClass - getting current authenticated user
ConsoleLogger.js?36de:107 [DEBUG] 00:18.534 Hub - Dispatching to UI Auth with {event: "AuthStateChange", message: "signedin", data: CognitoUser}
ConsoleLogger.js?36de:97 [DEBUG] 00:18.534 AuthClass - getting current authenticated user
ConsoleLogger.js?36de:107 [DEBUG] 00:18.535 Hub - Dispatching to UI Auth with {event: "AuthStateChange", message: "signedin", data: CognitoUser}
ConsoleLogger.js?36de:97 [DEBUG] 00:18.535 AuthClass - get current authenticated userpool user
ConsoleLogger.js?36de:97 [DEBUG] 00:18.537 AuthClass - get current authenticated userpool user
ConsoleLogger.js?36de:107 [INFO] 00:18.542 Authenticator - Inside onAuthStateChange Method current authState: loading
ConsoleLogger.js?36de:107 [INFO] 00:18.543 Authenticator - Auth Data was set: CognitoUser {username: "paragbaxi", pool: CognitoUserPool, Session: null, client: Client, signInUserSession: CognitoUserSession, …}
ConsoleLogger.js?36de:97 [INFO] 00:18.543 Authenticator - authState has been updated to signedin

@ericclemmons
Copy link
Contributor

@paragbaxi Can you share sample code for your scenario? withAuthenticator listens to authentication events, which may be why it works but the app doesn't without it.

@paragbaxi
Copy link

@ericclemmons , my apologies, I don't have it as I ended up going the HoC route and calling appsync via the client side (on Next.js). If I run into it again, I'll paste it here.

@ericclemmons
Copy link
Contributor

@janhesters Were you able to resolve the login flow issue? Based on the discussions before, our pre-built authenticator would've been used to validating that the backend/frontend are configured correctly. With that validated, then the solution would be in the implementation (e.g. calling Auth. completeNewPassword after Auth.signIn).

@stale
Copy link

stale bot commented Nov 16, 2020

This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.

@stale stale bot closed this as completed Nov 16, 2020
@shawntharoo
Copy link

I also got the same issue in my react app which use "aws-amplify": "^3.3.24". the user sign in successfully but when i refresh the page, first i call the "Auth.currentAuthenticatedUser" method to get the user data. but it always return "The user is not authenticated".
Any updates on this?

@eherms
Copy link

eherms commented Jun 1, 2021

Yeah this is a problem. Upgraded to amplify 4.0.3 and now when I try to run Auth.currentAuthenticatedUser() in my getServerSideProps function, it returns with 'The user is not authenticated', but when I run a helper function that runs Auth.currentAuthenticatedUser() in the same page outside the getServerSideProps function, it returns with the signed in user. Bewildering. Worked fine before the upgrade to amplify 4.0.3.

@gmeligio
Copy link

I solved it using the exact version for @aws-amplify/auth (3.4.28) that the packages @aws-amplify/ui-components and @aws-amplify/ui-react depended on. Found the version with yarn why @aws-amplify/auth. Trying the same minor or major version didn't work in my case.

I'm using a combination of the AmplifyAuthenticator component for authentication and Auth.currentAuthenticatedUser to get the user in other components. Everything was working fine with the functions of AmplifyAuthenticator, but when I changed the flow in other components to use Auth.currentAuthenticatedUser, I got the issue discussed here.

Here is the relevant part of package.json where I solved the problem:

{
  "@aws-amplify/api": "^3.2.30",
  "@aws-amplify/auth": "3.4.28",
  "@aws-amplify/core": "^3.8.20",
  "@aws-amplify/ui-components": "^1.3.2",
  "@aws-amplify/ui-react": "^1.0.5"
}

@beppek
Copy link

beppek commented Aug 11, 2021

I solved this by adding the bypassCache param to the currentAuthenticatedUser call like so:

Auth.currentAuthenticatedUser({ bypassCache: true })

@eherms
Copy link

eherms commented Aug 17, 2021

Started a whole new project and problem went away, but I'll try the bypassCache if it pops up again. Thanks @beppek !

@joekendal
Copy link

joekendal commented Aug 17, 2021

@beppek this does not seem to work. And for some reason, this only occurs for me on mobile or when being redirected back to the site

@beppek
Copy link

beppek commented Aug 17, 2021

@joekendal @eherms yeah it's weird. The day after I posted that it stopped working for me again for a different reason which I can't remember now. Removed bypassCache and fixed the other issue I had and it worked. So bypassCache was probably not the solution.

That's the only thing I did that made it work at first though but now that it's gone it still works. Perhaps my cached user was messed up somehow 🤷‍♂️

@chrisbonifacio
Copy link
Member

If using getServerSideProps, is everyone also configuring Amplify with ssr to be true like so?

Amplify.configure({ ...awsconfig, ssr: true })

This may fix the issue on the client but also with it you should be able to use withSSRContext in getServerSideProps to reinitialize Auth with the user credentials from the request.

Please let me know if you are already doing this and still running into issues. If not, let me know if that helps at all.

@github-actions
Copy link

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Auth Related to Auth components/category SSR Issues related to Server Side Rendering to-be-reproduced Used in order for Amplify to reproduce said issue
Projects
None yet
Development

No branches or pull requests