Is it possible to modify AWS Cognito user attributes in the Lambda triggers

前端 未结 4 1357
说谎
说谎 2021-02-18 14:58

Having a look at the AWS documentation,

https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html#cogni

相关标签:
4条回答
  • 2021-02-18 15:42

    For anyone else looking into insight on this question, here is an example below

    The lambda function #1 below takes into two custom attributes ida and ethaddress. The lambda is invoked during the PreSignUpHook for Cognito user pools

    #2 (Before event changed logs) the original values for these attributes is ida=1 and ethaddress=ABCD

    #3 (After event changed logs) reflects the changed values of these attributes: ida=2 and ethaddress=EFGH

    However the values which are saved to cognito are the original ones: ida=1 and ethaddress=ABCD. Therefore updateing the userAttributes during the presignuphook does NOT work as suggested in some of the answers.

    On a side note when the predefined attributes in the response object are modified they are updated as expected:

    "response": {
        "autoConfirmUser": true,
        "autoVerifyEmail": false,
        "autoVerifyPhone": false
    }
    
    1. LAMBDA:
    'use strict';
    global.fetch = require('node-fetch')
    
    module.exports.preSignUp = async (event, context, callback) => {
    // Set the user pool autoConfirmUser flag after validating the email domain
    
    let data = await fetch("http://***.***.***/api/members/create",
    {
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        method: "POST",
    })
    .then(res => res.json())
    .then(res => res);
    
    event.response.autoConfirmUser = true;
    console.log('before event:', JSON.stringify(event)); 
    event.request.userAttributes['custom:ethaddress'] = String(data.address); 
    event.request.userAttributes['custom:ida'] = "2";  
    console.log('Received event:', JSON.stringify(event));  
    console.log('Address:', data.address);
    
    
     // Return to Amazon Cognito
    callback(null, event);
     };
    
    2.

    BEFORE EVENT CHANGE LOG:

    2019-01-20T01:02:24.639Z    edce636e-75ea-492b-b6a0-dd4f22dc9038    before event:
    {
        "version": "1",
        "region": "us-east-1",
        "userPoolId": "us-east-1-*****",
        "userName": "*******@gmail.com",
        "callerContext": {
            "awsSdkVersion": "aws-sdk-unknown-unknown",
            "clientId": "******************"
        },
        "triggerSource": "PreSignUp_SignUp",
        "request": {
            "userAttributes": {
                "custom:ida": "1",
                "custom:ethaddress": "ABCD",
                "email": "*******@gmail.com"
            },
            "validationData": {}
        },
        "response": {
            "autoConfirmUser": true,
            "autoVerifyEmail": false,
            "autoVerifyPhone": false
        }
    }
    
    3 .

    AFTER EVENT CHANGE LOG:

    Received event:
    {
        "version": "1",
        "region": "us-east-1",
        "userPoolId": "us-east-1_0BaE6eaTY",
        "userName": "*******@gmail.com",
        "callerContext": {
            "awsSdkVersion": "aws-sdk-unknown-unknown",
            "clientId": "*****************"
        },
        "triggerSource": "PreSignUp_SignUp",
        "request": {
            "userAttributes": {
                "custom:ida": "2",
                "custom:ethaddress": "EFGH",
                "email": "*******@gmail.com"
            },
            "validationData": {}
        },
        "response": {
            "autoConfirmUser": true,
            "autoVerifyEmail": false,
            "autoVerifyPhone": false
        }
    }
    

    UPDATE:

    It seems like there is no way to do this as a part of the PRESIGNUP process However it is possible to do this as a POSTCONFIRMATION trigger in cognito example provided below.

    Some things to watch out for.

    1. the custom attribute has added in cognito and is mutable.
    2. in App client --> show details --> "Set attribute read and write permission" Ensure there is below read and write perms on the custom attribute.
    3. Ensure that the lambda function has a ROLE which allows it to execute: adminUpdateUserAttributes E.g. Attach AmazonCognitoPowerUser Policy to the LambaRole.
    module.exports.postConfirmation = async (event, context,callback) => {
            const cognitoIdServiceProvider = new CognitoIdentityServiceProvider({
              region: 'us-east-1'
            });
    
            var params =  {
                UserAttributes: [
                  {
                      Name: 'custom:sillyName',
                      Value: 'customSillyName'
                  }
                ],
                UserPoolId: event.userPoolId,
                Username: event.userName
            }
    
            cognitoIdServiceProvider.adminUpdateUserAttributes(params, function(err, data) {
              if (err) console.log(err, err.stack); // an error occurred
              else     console.log(data);           // successful response
            }); 
    
            callback(null,event);
    
    };
    

    Note if you attempt to user cognitoIdServiceProvider.adminUpdateUserAttributes in the preSignUp trigger hook you;ll get an exception saying the user does not exit yet

    0 讨论(0)
  • 2021-02-18 15:45

    There isn't a way to mutate/augment attributes during sign up, but during sign in, you can mutate/augment them with the pre-token generation trigger.

    0 讨论(0)
  • 2021-02-18 15:48

    Well, the simple solution would be like so, adding this to the "Pre Sign-up Lambda function", taking cue from your code:

    // Modify an existing username...
     event['request']['userAttributes']['name'] = "My_NAME";
    
    // Add an additional attribute...
     event['request']['userAttributes']['custom:sillyname'] = "ANY_NAME";
    
     callback(null, event);
    

    Considering you have added the custom:sillyname attribute for the user pool.

    0 讨论(0)
  • 2021-02-18 16:04

    Yes, there's absolutely a way! You need to use AWS javascript SDK in your Lambda handler:

    const AWS = require('aws-sdk');
    AWS.config.update({region: 'ap-southeast-1'});
    
    const cognitoidentityserviceprovider =
      new AWS.CognitoIdentityServiceProvider({
        apiVersion: '2016-04-18'
      });
    cognitoidentityserviceprovider.adminUpdateUserAttributes(
      {
        UserAttributes: [
          {
            Name: 'YOUR_USER_ATTRIBUTE_NAME',
            Value: 'YOUR_USER_ATTRIBUTE_VALUE'
          }
        ],
        UserPoolId: event.userPoolId,
        Username: event.userName
      },
      function(err, data) {
        ...
      }
    );
    

    Make sure to give your Lambda function the right policies (i.e. allows "cognito-idp:AdminUpdateUserAttributes" action) and the user pool has the attribute defined.

    0 讨论(0)
提交回复
热议问题