alt*_*tus 18 triggers amazon-cognito aws-lambda
看一下AWS文档,
您在Pre Sign-up Lambda功能中有以下参数 :
"request": {
"userAttributes": {
"string": "string",
....
},
"validationData": {<validation data as key-value (String, String) pairs, from the client>}
Run Code Online (Sandbox Code Playgroud)
有没有办法修改或添加其他userAttributes事件对象?
例如:
// Modify an existing username...
event.request.userAttributes.name.ucfirst();
// Add an additional attribute...
event.request.userAttributes.nickname = "ANY_NAME";
callback(null, event);
Run Code Online (Sandbox Code Playgroud)
是的,绝对有办法!您需要在Lambda处理程序中使用AWS javascript SDK:
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) {
...
}
);
Run Code Online (Sandbox Code Playgroud)
确保为Lambda函数提供正确的策略(即允许"cognito-idp:AdminUpdateUserAttributes"操作),并且用户池已定义属性.
对于任何其他人想要深入了解这个问题,下面是一个例子
下面的 lambda 函数 #1 包含两个自定义属性ida
和ethaddress
. 在 Cognito 用户池的 PreSignUpHook 期间调用 lambda
#2(在事件更改日志之前)这些属性的原始值是ida=1
和ethaddress=ABCD
#3(事件更改日志后)反映了这些属性的更改值:
ida=2
和ethaddress=EFGH
但是,保存到 cognito 的值是原始值:ida=1
和ethaddress=ABCD
. 因此,在 presignuphook 期间更新 userAttributes 不会按照某些答案中的建议工作。
另外,当响应对象中的预定义属性被修改时,它们会按预期更新:
"response": {
"autoConfirmUser": true,
"autoVerifyEmail": false,
"autoVerifyPhone": false
}
Run Code Online (Sandbox Code Playgroud)
1. 拉姆达:
'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);
};
Run Code Online (Sandbox Code Playgroud)
2.
事件更改日志之前:
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
}
}
Run Code Online (Sandbox Code Playgroud)
3 .
事件更改日志后:
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
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
似乎没有办法在 PRESIGNUP 过程中执行此操作,但是可以在下面提供的 Cognito 示例中将其作为 POSTCONFIRMATION 触发器执行。
需要注意的一些事情。
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);
};
Run Code Online (Sandbox Code Playgroud)
请注意,如果您尝试cognitoIdServiceProvider.adminUpdateUserAttributes
在 preSignUp 触发器挂钩中使用用户;将收到一个异常,说明用户尚未退出
为了填写@Khoi 非常有用的答案的一些细节,并且对于所有剪切和粘贴的人(您知道自己是谁),这里有一个 Lambda 模板,该模板运行 Cognito 用户池后确认触发器。
Lambda 在用户的自定义属性中设置一个新值,在本例中为“fruit”。以下是实施雷区中需要避免的一些问题:
let a = user.attributes['custom:fruit']
const aws = require('aws-sdk');
const cisProvider = new aws.CognitoIdentityServiceProvider({ apiVersion: '2016-04-18' });
// Cognito User Pool Lambda triggers are documented here:
// https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html
exports.lambdaHandler = async (event, context, callback) => {
const params = {
UserPoolId: event.userPoolId,
Username: event.userName,
UserAttributes: // this parameter needs to be an array
[
{
Name: 'custom:fruit',
Value: 'banana'
}
]
};
if (event.request.userAttributes.email) {
try {
await cisProvider
.adminUpdateUserAttributes(params)
.promise();
console.log('Success');
} catch (error) {
console.error('Error', error);
}
}
callback(null, event);
};
Run Code Online (Sandbox Code Playgroud)
如果您正在使用 AWS SAM(正如我希望的那样)来调试和部署 Lambda,那么这里是该 Lambda 的模板。请注意角色资源。在部署 Lambda 之前,您需要在 AWS 控制台中定义此 IAM 角色。可能有一种方法可以在模板中定义角色,但我不是 AWS YAML 方面的专家。使用 SAM CLI 命令将 Lambda 部署到您的 AWS 账户
sam deploy --guided
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
SAM Template for lambda function that runs as a Cognito User Pool post confirmation trigger.
Cognito invokes this function when a new user signs up.
Globals:
Function:
Timeout: 3
Resources:
PostConfirmationFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: post-confirmation/
Handler: app.lambdaHandler
Runtime: nodejs14.x
Role:
# This role gives Lambda permission to update user pool attributes as well as basic execution.
arn:aws:iam::xxxxxxxxxxxx:role/lambda-cognito-update-role
Outputs:
PostConfirmationFunction:
Description: "Post Confirmation Lambda Function ARN"
Value: !GetAtt PostConfirmationFunction.Arn
Run Code Online (Sandbox Code Playgroud)
您需要在 IAM 控制台中创建一个包含更新用户属性的权限的角色。我更喜欢使用“内联策略”来执行此操作,以避免我的账户中 IAM 策略激增且依赖性不明确。我发现做到这一点的最佳方法是两步过程:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CognitoUpdate",
"Effect": "Allow",
"Action": "cognito-idp:AdminUpdateUserAttributes",
"Resource": "*"
}
]
}
Run Code Online (Sandbox Code Playgroud)
可以说,资源应该更具体,可能仅限于您帐户中的用户池。我将其留给您自行决定。