amplify-js: currentSession() returns no current user?

I’m trying to test with the following code in a component that is wrapped by the withAuthenticator() HOC. Federated login works. Once logged in, I get the “No current user” error when running the following code, but the user object is getting populated.

Am I not understanding how the library works? Shouldn’t the currentSession return JWT, acesstoken, id?

Ultimately, I want to be able to get email from Facebook as identity provider.

componentDidMount = () => {
    window.LOG_LEVEL = 'DEBUG'
    console.log("About to mount")
    Auth.currentSession().then(function(session) {
      console.log(JSON.stringify(session))
    }, function(err) {
      console.log(err)
    })
    Auth.currentAuthenticatedUser().then(function(user) {
      console.log("USER: " + JSON.stringify(user))
    })
  }

Output:

No current user
USER: {"Name":"x x"}

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 18
  • Comments: 85 (21 by maintainers)

Most upvoted comments

I’m facing the exact same problem and, I have to say, I feel a little frustrated…

I expected signIn and federatedSignIn to to be only different ways to authenticate the user… I understand user and identity pools have different goals but at this point (as a developer), I just need a simple, unified way to authenticate users, be able to identify them (from the token, server-side) and use services.

PS: @mlabieniec, this issue was closed by inactivity but I think it should be reopened…

From conversations from other issues, one thing is clear to me : Auth.federatedSignIn has no relation with Auth.currentSession & Auth.currentAuthenticatedUser. When I login via Cognito User Pool and call Auth.currentSession &orAuth.currentAuthenticatedUser, I get JWT token which I can use to access my APIs. But, the response of Auth.federatedSignIn is an object of CognitoIdentityCredentials and this object does not have a JWT token. So, my question is how do I get a JWT token when I login using Auth.federatedSignIn. A lot of the issues on this repo (#699 , #542 , #793 , #703 )ask this question with no definitive answer.

@powerful23 The token from federatedInfo returns the jwt token received from Facebook. I cannot use that to access my APIs in AWS. I get 401 when making API calls I am talking about a jwt token similar to what Congnito provides, that can be used for accessing my APIs in AWS. Referring to the code example from the docs:

When using Cognito User Pool

Auth.signIn(username, password)
    .then(user => console.log(user))
    .catch(err => console.log(err));
let session = Auth.currentSession(); // THIS PROVIDES THE JWT TOKEN IN CASE OF COGNITO USER POOL

When using Federated SignIn (Facebook example)

export default class App extends React.Component {
  async signIn() {
    const { type, token, expires } = await Expo.Facebook.logInWithReadPermissionsAsync('YOUR_FACEBOOK_APP_ID', {
        permissions: ['public_profile'],
      });
    if (type === 'success') {
      // sign in with federated identity
      Auth.federatedSignIn('facebook', { token, expires_at: expires}, { name: 'USER_NAME' })
        .then(credentials => {
          console.log('get aws credentials', credentials);
// HOW DO I GET A VALID JWT TOKEN HERE TO ACCESS MY APIs
        }).catch(e => {
          console.log(e);
        });
    }
  }

Getting the same thing. currentSession works with normal login, but with federated login I get No current user

Please update your documents to reflect this AWS. Very frustrating.

dont take it as 100% bullet proof, as i am not an AWS employee, this summary is only according to my experience with AWS cognito. TL:DR

  1. AWS Cognito documentation is bad, it is confusing regarding its components (user pool, identity pool), and miss-leading about what it can and can’t do and how.
  2. The cognito SDK, isn’t sufficient, isn’t well enough documents, and rarely have code examples - reference guide, isn’t enough.
  3. Its high cost, isn’t its monthly usage, it’s the too much time, took too many developers, to figure out it doesn’t answer their basic needs.
  4. If you are looking for authentication solution, and want to write your own UI - it is probably isn’t the solution for you – currently, hope they will chose to support it in future.

Cognito overview:

  1. User pools – create users authentication records: a. Save user attributes b. Authenticate users with user and password c. Email / phone verification d. Access the user details from SDK
  2. Federation identity (identity pools) a. Required in order to get temporary token, to access amazon resources (S3, Api gateway etc) b. It federate – i.e. gives temporary token, to users from external sources: i. User pools ii. Facebook App / Google App c. Identity record being created – in the (federated) identify pool, NOT in users pool, but you cannot get user details by token, credentials, or any other identity field. 3. Cognito Buildin-UI enable you to have a flow of creating user in User pool, and get federation identity created when needed to access AWS services. The user can be created with both user & password or with Social services (fb, google etc) This UI, is the ONLY method, to create a user in the user pool, from social login. 4. If you want to implement your own UI, you depends on the SDK, and can create user only with user & password, not through social login. 5. The SDK is limited, and different from one language to another: a. you cannot create a user from social login b. you cannot create a user without a password c. you cannot fetch user information from Federated identity d. you can fetch user information from user pool, but this user exist only if you user user & password / you used the build-in UI to create it.

Recommendation: 1. If you are building a web-app, NOT a mobile app, and doesn’t need advanced user registration / login, the Built-in UI may be good enough for you, and you may benefit from Cognito full solution, having all your users in the user pool, and get the access from federated. 2. If you don’t need to have your own users, and just want to enable social users to get temporary access to AWS resources – you just need federated login. 3. If you don’t want to use the Build-in UI, and want a social login – you will not be able to use the cognito SDK to manage your users, and you will need to have your own solution for one unified users table + basic abilities, example of problematic use cases: a. user registered with email + password, and later on, sign-in with facebook connect, you need to know it is the same user. b. You want to have user id for each user. c. You have a server side, that needs to know who is the currently logged in user, and you don’t want to make it integrate with multiple social services, but with a single users API.

@vsrivatsan89 The currentSession only works when you logged in with Cognito Userpool. We will work on the naming to make it more clear. Thanks!.

@kanteankit Your should get an Authorization token from your auth provider. Once you get that token you can do this.

var provider_url = 'my.auth-provider.com';
await Auth.federate(provider_url, { token: id_token });
var credentials = await Auth.currentUserCredentials();

@elorzafe As mentioned in my previous comments,I am familiar with Amazon Cognito and I am already using Auth.signIn for authenticating via email. That email authentication is creating a user in Cognito User Pool and giving me a JWT token that I can use in Authorization header.

The entire point of my question is how can I do a similar thing with Auth.federatedSignIn. After calling Auth.federatedSignIn, what should I do to get an Authorization token?

Note: I cannot use awsmobile-cli.

facing the same problem (logged in with Cognito Userpool) but after changed the amplify configuration from

Amplify.configure({
  Auth: {
    region: 'xx-xxxxx',
    identityPoolId: 'xx-xxxxxx',
    userPoolId: 'xx-xxxx',
    userPoolWebClientId: 'xxxxxxxxx',
    mandatorySignIn: false,
    storage: xxxxx,
  }
});

to

Amplify.configure({
  Auth: {
    region: 'xx-xxxxx',
    userPoolId: 'xx-xxxx',
    userPoolWebClientId: 'xxxxxxxxx',
    aws_appsync_authenticationType: 'AMAZON_COGNITO_USER_POOLS'
  }
});

then place it in your app’s entry point i.e. App.js, currentSession() now worked

How to get Cognito Tokens when Authenticating with Social Providers

  1. You need to Setup your Auth Provider with Cognito User Pools. More info here
  2. On your App you have to call Auth.federatedSignIn in this way
    1. Auth.federatedSignIn() this will open Cognito Hosted UI Web App.
    2. In case you want to skip Cognito Hosted UI you can invoke from your App
      1. Auth.federatedSignIn({provider: 'Facebook'})
      2. Auth.federatedSignIn({provider: 'Google'})
      3. Auth.federatedSignIn({provider: 'LoginWithAmazon'})
      4. Auth.federatedSignIn({provider: 'SignInWithApple'})

Then you will have a user on your userpool and Cognito tokens on your App.

Note If you get a token from your Authentication Provider and then use

Auth.federatedSignIn(
    domain,
    {
        token,
        identity_id, // Optional
        expires_at: expiresIn * 1000 + new Date().getTime() // the expiration timestamp
    },
    user
)

You wont be able to get a Cognito Tokens and you will No current user error.

Why is this issue closed? We are facing the same problem right now – can’t use graphQL resource with federated signin

@mlabieniec I am experiencing the same issue. You are still not getting what @kanteankit is saying.

We are talking about the JWTOKEN from Cognito. Not the one from the identity provider(eg. Facebook, Google.)

After using Auth.federatedSignIn it only returns the Cognito credentials Obj. So the question is, How do we get the JWTTOKEN from Cognito after the use of Auth.federatedSignIn?

@GenghisJuan you right, it is the most basic - except if u develop a website, and can use the hosted UI. I was also sure that it had to be possible - and if I didn’t got it to work, I must have done something wrong, it took me 5 weeks to give up and share my lesson here in details to save other developers the frustration. (Scroll up if u missed it) 😉 so feel free to waste your time, don’t forget to let us know how was it…

I too have been hacking around here trying to find out a solution. Just to be clear, if I am using react-native + amplify, there is no way to have a user sign up with Facebook and have that user in my Cognito user pools? This is like the most basic use case, hard to believe it isn’t supported.

Facing the same issue:

I’ve created my own identity pool in cognito. For the server/client auth workflow I followed this documentation:

https://docs.aws.amazon.com/cognito/latest/developerguide/developer-authenticated-identities.html

https://docs.amplify.aws/lib/auth/advanced/q/platform/js#identity-pool-federation

Server side code to create the token/identityId:

  var params = {
    IdentityPoolId: 'us-east-1:MY_ID_POOL',
    IdentityId: null,
    Logins: {
      'mycomp.es': jwttoken
    },
    TokenDuration: '86400'
  };

  var cognitoidentity = new AWS.CognitoIdentity();
  const logres = cognitoidentity.getOpenIdTokenForDeveloperIdentity(params, function (err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else console.log(data);           // successful response
  });

The result:

{
  IdentityId: 'us-east-1:IDENTITY_ID',
  Token: 'eyJra.... rest of the token'
}

With the Client side code, I was able to create the credentials:

        const domain = 'cognito-identity.amazonaws.com';
        const federatedUser = {
            name: 'the_user',
            email: 'the_email@gmail.com'
        };

        Auth.federatedSignIn(
            domain,
            {
                token: tokenResponse.Token, // this is the token generated
                identity_id: tokenResponse.IdentityId, // this is the identiy Id
                expires_at: 50 * 1000 + new Date().getTime() // the expiration timestamp
            },
            federatedUser
        ).then(cred => {
            // If success, you will get the AWS credentials
            console.log(cred);
            return Auth.currentAuthenticatedUser();
        }).then(user => {
            // If success, the user object you passed in Auth.federatedSignIn
            console.log("success", user);
            fetch();
        }).catch(e => {
            console.log(e)
        });

This returns no error, and the objects created seems correct:

Credentials:


{
  "accessKeyId": "xxx",
  "secretAccessKey": "yyy",
  "sessionToken": "zzz",
  "expiration": "2020-08-22T09:36:14.000Z",
  "authenticated": true
}

User:

{
  "name": "the_user",
  "email": "the_email@gmail.com"
}

But despite that I cannot access to any AWS resources yet, like graphql. I keep getting the following error:

No current user

I’m experiencing the same issue. To clear this up when you create an API and add an Authenticator to it, it expects a Token to prove that the user accessing the API came from cognito, i.e. it is safe to provide access.

When you call Auth.currentSession() after a cognito user pool login you are given the following response CognitoUserSession {idToken: CognitoIdToken, refreshToken: CognitoRefreshToken, accessToken: CognitoAccessToken, clockDrift: 0} accessToken: CognitoAccessToken {jwtToken: "xxxxxxx", payload: {…}} clockDrift: 0 idToken: CognitoIdToken jwtToken: ****[THIS IS USED FOR API CALLS]**** payload: xxxx __proto__: CognitoJwtToken refreshToken: CognitoRefreshToken {token: "xxxxxxxx"} __proto__: Object

The idToken->jwtToken is the token needed to authorize API calls.

When Auth.currentSession() is called after a federated sign in, the following is returned : no current user.

How can we get a valid jwt token from a federated sign-in user?

Has there been any updates?

Far out, I can’t believe this is still open with no real resolution. We have got up until federatedSignIn and now need JWT to access the Amplify GraphQL API. Have tried this with both Facebook login and a developer identity.

Can someone from AWS confirm that there is no other solution than to create a hosted UI?

@mayteio yes, so the federatedSignIn method only works with Cognito Federation Identity Pool to by passing the JWT token from third provider to get a temporary AWS credentials. If you want to do federation with Cognito User Pool and get a JWT token from it, you have to use Cognito Hosted UI.

@eyalc4 thanks for your feedback.

Sad to see this issue closed.

I got the same error while using the Authenticator from aws-amplify-react, after logging in with facebook Auth.currentSession() returned No current user.

But if I use Auth.federatedSignIn(), Auth.currentSession() returns an access token that I can use. And I can skip displaying the hosted UI by naming a provider as a parameter Auth.federatedSignIn({provider: 'Facebook'})

So do not use the facebook sign in button on the <Authenticator /> component if you want an access token. Do use the Auth.federatedSign({provider: 'provider-name'}) to get an access token and skip the UI.

Here are some sample code, replace the variables for your user pool with your own:

import React from "react";
import Amplify, { Auth, Hub } from "aws-amplify";

Amplify.configure({
  Auth: {
    region: "eu-central-1",
    userPoolId: "eu-central-1_xxxxx",
    userPoolWebClientId: "xxxxxxxxx"
  }
});

const oauth = {
  domain: "your_domain.auth.eu-central-1.amazoncognito.com",
  scope: ["email", "profile"],
  redirectSignIn: "http://localhost:3000",
  redirectSignOut: "http://localhost:3000",
  responseType: "code"
};

Auth.configure({ oauth });

class App extends React.Component {
  state = {
    session: null
  };

  constructor() {
    super();
    Hub.listen("auth", ({ payload: { event, data } }) => {
      switch (event) {
        case "signIn":
          console.log("Sign in");
          this.setSession();
          break;
        case "signOut":
          console.log("Sign out");
          break;
        default:
          break;
      }
    });
  }

  setSession = async () => {
    const session = await Auth.currentSession();
    this.setState({ session });
  };

  render() {
    const { session } = this.state;

    return (
      <div className="App">
        <button onClick={() => Auth.federatedSignIn({ provider: "Facebook" })}>
          Facebook
        </button>
        <button onClick={() => Auth.federatedSignIn()}>Open Hosted UI</
        <p>{JSON.stringify(session)}</p>
      </div>
    );
  }
}

export default App;

Thanks @powerful23 though that does not help. It just passes me back the info I passed into the user argument of federatedSignIn(provider, response, user). No JWT in sight.

Thanks @nickadiemus, I thought you made it work without hosted UI, that’s the main issue here. Looks like there is no way of getting AWS token without using hosted UI.

@kanteankit you can get the jwt token by using the Cache:

import { Cache } from 'aws-amplify';

// in web
const federatedInfo = Cache.getItem('federatedInfo');
const { token } = federatedInfo;

// in reactNative
Cache.getItem('federatedInfo').then(federatedInfo => {
     const { token } = federatedInfo;
});

Sorry we didn’t mention this in the doc, will send a pr for that.

For federate signin & currentSession() to be working,

i would mean “jwt token(accessToken, idToken) & refreshToken returned from the call properly, so those session refresh etc would still be handled by aws-amplify and one can further call essentialCredentials() to call other create service instance later”, like

    const result = await Auth.currentCredentials();
    const credentials = Auth.essentialCredentials(result);
    $logger.info(credentials);
    const s3 = new S3({
      credentials,
      region,
      // https://github.com/aws/aws-sdk-js/issues/902#issuecomment-184872976
      signatureVersion: 'v4'
    });

This is the full approach working for us: giving up approaches federatedSignIn() and UI componenet implementation that are based on hosted ui and craft corresponding oauth link for federated signin. We implemented it for google federated sigin.

On signin page

    async signInWithGoogle() {
      const config = Auth.configure();
      const {
        domain,
        redirectSignIn,
        redirectSignOut,
        responseType,
        scope
      } = config.oauth;
      const clientId = config.userPoolWebClientId;
      const url = `https://${domain}/oauth2/authorize?identity_provider=Google&redirect_uri=${redirectSignIn}&response_type=${responseType}&client_id=${clientId}`;
      window.location.assign(url);
    }

On the oauth returnUrl, do parsing according to the workaround mentioned in https://github.com/aws-amplify/amplify-js/issues/1316#issuecomment-409290894

  authClient.userhandler = {
    onFailure: err => {
      // ? NOTE: This is still necessary, would be called once before the response ready to be parsed.
      $logger.info('userhandler onFailure');
      $logger.info('Error in cognito hosted auth response', err);
    },
    onSuccess: result => {
      $logger.info('userhandler onSuccess');
      Auth.currentSession().then(async data => {
        const userInfo = await Auth.currentUserInfo();
        $logger.info(userInfo);
        // ? NOTE: Remove the param of intermediate exchange code in url even though it is for 1-time-use.
        // This stops entering the flow again.
        app.router.replace('/dashboard/');
      });
    }
  };
  const codeForExchangeToken = new URL(curUrl).searchParams.get('code');
  if (codeForExchangeToken) {
    $logger.info(`Exchange code: ${codeForExchangeToken}`);
    authClient.parseCognitoWebResponse(curUrl);
  } else {
    Auth.currentSession().catch(err => {
      // ? NOTE: onReady event is needed to make it works here
      app.router.onReady(event => {
        app.router.replace('/user/signIn/');
      });
    });
  }

I’m using cognito hosted UI and trying to authenticate to appsync. I followed these instructions: https://aws-amplify.github.io/docs/js/react#add-graphql-backend With the same configuration, the only difference is that I have federated auth. I also get a “No current user” error, even though the hosted cognito UI says I’m logged in (via google). As a developer I’d expect once someone signs in via the cognito hosted UI, I’d be able to make appsync requests for my appsync service configured to permit via cognito. The fact someone is signed in via federated identity should not matter.

hey guys, i’m using the Auth.signIn() method which returns a CognitoUser object and among its properties, the signInUserSession has a value of null.

and when i ran await Auth.currentSession() i got ‘No current user’ as well.

if it helps, i’m following a tutorial and this is the step i’m currently on when i encountered this issue.

EDIT: i looked through the properties of the CognitoUser object again and found a property called session

I’m struggling with it, no way without hosted UI… I’m very frustrated!!

@powerful23 Thank you for the prompt response. I think there is some confusion regarding which JWT tokens each of us is talking about.

When doing authentication via Auth.signIn & calling Auth.currentSession I get an object of CognitoUserSession which contains JWT . Now when making an API call I can get the JWT and set the header as follows:

 Auth.currentSession()
     .then((response) => {
         authToken =  response.idToken.jwtToken
         headers = { 
            'authorization': authToken
          } 
        // API call logic follows ....
 })

In case of federatedSignIn, I can’t figure out how to get this kind of JWT token that can be passed in the header. I get a token from Facebook that I pass along to Auth.federatedSignIn as shown in my previous comment, but, then, what should I do to get an authentication token for making API calls?