question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

User is not authenticated error when trying to update user attributes

See original GitHub issue

** Which Category is your question related to? ** Cognito user authentication

** What AWS Services are you utilizing? ** Cognito

** Provide additional details e.g. code snippets ** Hi,

I’m trying to implement Amazon Cognito authentication in my Angular 6 application. I can connect my user, but I want to give the users the ability to change their informations, so I created a new service to update user attributes. But when I launch the update method, I get a User is not authenticated error. I’m still in the phase of learning Cognito, even though I have a much better understanding of how it works.

So here is the code to handle the login:

export class UserLoginService {
  private onLoginSuccess = (callback: CognitoCallback, session: CognitoUserSession) => {
    AWS.config.credentials = this.cognitoUtil.buildCognitoCreds(session.getIdToken().getJwtToken());
    const idToken: any = session.getIdToken();
    const mongoId = idToken.payload['custom:mongo_id'];
    const mongoUser = this.mongoUserService.getUser(mongoId, true).subscribe();

    // So, when CognitoIdentity authenticates a user, it doesn't actually hand us the IdentityID,
    // used by many of our other handlers. This is handled by some sly underhanded calls to AWS Cognito
    // API's by the SDK itself, automatically when the first AWS SDK request is made that requires our
    // security credentials. The identity is then injected directly into the credentials object.
    // If the first SDK call we make wants to use our IdentityID, we have a
    // chicken and egg problem on our hands. We resolve this problem by 'priming' the AWS SDK by calling a
    // very innocuous API call that forces this behavior.
    const clientParams: any = {};
  }

  private onLoginError = (callback: CognitoCallback, err) => {
    callback.cognitoCallback(err.message, null);
  }

  constructor(
    public cognitoUtil: CognitoUtil,
    private authActions: AuthActions,
    private mongoUserService: MongoUserService,
    private dialogService: DialogService) {
  }

  authenticate(username: string, password: string, callback: CognitoCallback) {
    console.log('UserLoginService: starting the authentication');

    const authenticationData = {
      Username: username,
      Password: password,
    };
    const authenticationDetails = new AuthenticationDetails(authenticationData);

    const userData = {
      Username: username,
      Pool: this.cognitoUtil.getUserPool()
    };

    const cognitoUser = new CognitoUser(userData);

    cognitoUser.authenticateUser(authenticationDetails, {
      newPasswordRequired: (userAttributes, requiredAttributes) => callback.cognitoCallback(`User needs to set password.`, null),
      onSuccess: result => this.onLoginSuccess(callback, result),
      onFailure: err => this.onLoginError(callback, err),
      mfaRequired: (challengeName, challengeParameters) => {
        callback.handleMFAStep(challengeName, challengeParameters, (confirmationCode: string) => {
          cognitoUser.sendMFACode(confirmationCode, {
            onSuccess: result => this.onLoginSuccess(callback, result),
            onFailure: err => this.onLoginError(callback, err)
          });
        });
      }
    });
  }
}

The part of the CognitoUtil class implied in the connection:

@Injectable()
export class CognitoUtil {

  public static _REGION = environment.region;

  public static _IDENTITY_POOL_ID = environment.identityPoolId;
  public static _USER_POOL_ID = environment.userPoolId;
  public static _CLIENT_ID = environment.clientId;

  public static _POOL_DATA: any = {
    UserPoolId: CognitoUtil._USER_POOL_ID,
    ClientId: CognitoUtil._CLIENT_ID
  };

  public cognitoCreds: AWS.CognitoIdentityCredentials;

  getUserPool() {
    if (environment.cognitoIdpEndpoint) {
      CognitoUtil._POOL_DATA.endpoint = environment.cognitoIdpEndpoint;
    }
    return new CognitoUserPool(CognitoUtil._POOL_DATA);
  }

  getCurrentUser() {
    return this.getUserPool().getCurrentUser();
  }

  getCognitoCreds() {
    return this.cognitoCreds;
  }

  // This method takes in a raw jwtToken and uses the global AWS config options to build a
  // CognitoIdentityCredentials object and store it for us. It also returns the object to the caller
  // to avoid unnecessary calls to setCognitoCreds.

  buildCognitoCreds(idTokenJwt: string) {
    let url = 'cognito-idp.' + CognitoUtil._REGION.toLowerCase() + '.amazonaws.com/' + CognitoUtil._USER_POOL_ID;
    if (environment.cognitoIdpEndpoint) {
      url = environment.cognitoIdpEndpoint + '/' + CognitoUtil._USER_POOL_ID;
    }
    const logins: CognitoIdentity.LoginsMap = {};
    logins[url] = idTokenJwt;
    const params = {
      IdentityPoolId: CognitoUtil._IDENTITY_POOL_ID, /* required */
      Logins: logins
    };
    const serviceConfigs = <awsservice.ServiceConfigurationOptions>{};
    if (environment.cognito_identity_endpoint) {
      serviceConfigs.endpoint = environment.cognito_identity_endpoint;
    }
    const creds = new AWS.CognitoIdentityCredentials(params, serviceConfigs);
    this.setCognitoCreds(creds);
    return creds;
  }


  getCognitoIdentity(): string {
    return this.cognitoCreds.identityId;
  }

  getAccessToken(callback: Callback): void {
    if (callback == null) {
      throw('CognitoUtil: callback in getAccessToken is null...returning');
    }
    if (this.getCurrentUser() != null) {
      this.getCurrentUser().getSession(function (err, session) {
        if (err) {
          console.log('CognitoUtil: Cant set the credentials:' + err);
          callback.callbackWithParam(null);
        } else {
          if (session.isValid()) {
            callback.callbackWithParam(session.getAccessToken().getJwtToken());
          }
        }
      });
    } else {
      callback.callbackWithParam(null);
    }
  }
}

And finally, the update attributes service that gives me the user is not authenticated error:

@Injectable()
export class UserUpdateService {

  constructor(@Inject(CognitoUtil) public cognitoUtil: CognitoUtil) {}

  update(userId: 'string', attributes: UpdateUser) {
    const attributeList = [];

    const dataPreferredUsername = {
      Name: 'preferred_username',
      Value: attributes.username
    };

    const dataEmail = {
      Name: 'email',
      Value: attributes.email
    };

    attributeList.push(new CognitoUserAttribute(dataPreferredUsername));
    attributeList.push(new CognitoUserAttribute(dataEmail));

    this.cognitoUtil.getCurrentUser().updateAttributes(attributeList, (err, result) => {
      if (err) {
        alert(err);
        return;
      }
      console.log('call result: ' + result);
    });
  }
}

If I log this.cognitoUtil.getCurrentUser() I have a user that corresponds to me, but the Session and signinUserSession are null.

I guess there’s an additional step I need to make, but I’m don’t know which one. Can anybody help?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
jbpratcommented, Sep 23, 2018

@richardzcode There is no MFA on my user, but I’ll try using Amplify instead of directly using Cognito!

1reaction
richardzcodecommented, Sep 22, 2018

Hey @jbprat one possible case is that MFA is required for your user. So until confirmed via SMS or TOTP the user is not really authenticated.

Actually with AWS Amplify you don’t need to interact with Cognito directly. Auth module of Amplify makes all these very easy.

import { Auth } from 'aws-amplify';

// Login
Auth.signIn(username, password)
  .then(user => console.log(user))
  .catch(err => console.log(err));

// Login confirmation
Auth.confirmSignIn(user, code)
  .then(() => console.log('confirm success'))
  .catch(err => console.log(err));

// Current user
Auth.currentAuthenticatedUser()
  .then(user => console.log(user))
  .catch(err => console.log(err));

// Update attribute
Auth.updateUserAttributes(user, attributes)
  .then(() => console.log('update success))
  .catch(err => console.log(err));

Once signIn happened you may check console logged ‘user’ object see if there is a user.challengeName property to make sure

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cognito user update attribute getting error - Error: User is not ...
I am getting Error: User is not authenticated error while updating user attribute. If this is not the way to update, please share...
Read more >
HTTP error 403 while trying to update user attributes via OTDS ...
HTTP error 403 while trying to update user attributes via OTDS RESTful API ... with HTTP code 403 - Access is denied to...
Read more >
Okta is not updating users attributes in some applications
Go to the applications settings in Okta > Provisioning > Integration and check the credentials for the API integration. This admin account is...
Read more >
PWM problem - can't update user profile - Google Groups
Right-click the top most OUs where your users are and under properties, security tab, you need to 'SELF' and then find the attribute...
Read more >
UpdateUserAttributes - Amazon Cognito User Pools
A valid access token that Amazon Cognito issued to the user whose user attributes you want to update. Type: String. Pattern: [A-Za-z0-9-_=.]+ Required:...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found