查看AWS文档,
您在 预注册 Lambda功能中可以使用以下参数:
"request": {
"userAttributes": {
"string": "string",
....
},
"validationData": {<validation data as key-value (String, String) pairs, from the client>}
有没有办法修改或添加其他 userAttributes 事件对象?
例如:
// Modify an existing username...
event.request.userAttributes.name.ucfirst();
// Add an additional attribute...
event.request.userAttributes.nickname = "ANY_NAME";
callback(null, event);
答案 0 :(得分:7)
是的,绝对有办法!您需要在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) {
...
}
);
确保为您的Lambda函数提供正确的策略(即允许“cognito-idp:AdminUpdateUserAttributes”操作),并且用户池已定义属性。
答案 1 :(得分:4)
在注册过程中,没有办法改变/扩充属性,但在登录期间,您可以使用pre-token generation trigger对其进行变异/扩充。
答案 2 :(得分:1)
对于任何想了解这个问题的人,下面是一个示例
下面的lambda函数#1具有两个自定义属性ida
和ethaddress
。 Lambda在Cognito用户池的PreSignUpHook期间被调用
#2(事件更改日志之前),这些属性的原始值为ida=1
和ethaddress=ABCD
#3(事件更改日志后)反映了这些属性的更改值:
ida=2
和ethaddress=EFGH
但是保存到认知模式的值是原始值:ida=1
和ethaddress=ABCD
。因此,按照某些答案中的建议,无法在presignuphook期间更新userAttributes。
另一方面,修改响应对象中的预定义属性后,它们会按预期进行更新:
"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。
事件更改日志之前:
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。
事后更改日志:
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
}
}
更新:
在PRESIGNUP过程中似乎没有办法做到这一点 但是,在下面提供的cognito示例中,可以将其作为POSTCONFIRMATION触发器。
需要注意的一些事情。
module.exports.postConfirmation =异步(事件,上下文,回调)=> {
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);
};
请注意,如果您尝试在preSignUp触发器挂钩中使用cognitoIdServiceProvider.adminUpdateUserAttributes
用户,您将得到一个异常,表明该用户尚未退出
答案 3 :(得分:1)
要填写有关@Khoi 非常有用的答案的一些详细信息,以及对于所有剪辑师(您知道自己是谁),这里是一个运行 Cognito 用户池发布确认触发器的 Lambda 模板。
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);
};
如果您使用 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
您需要在 IAM 控制台中创建一个角色,该角色包括更新用户属性的权限。我更喜欢使用“内联策略”来执行此操作,以避免在我的账户中因依赖项不明确而激增 IAM 策略。我发现做到这一点的最佳方法是一个两步过程:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CognitoUpdate",
"Effect": "Allow",
"Action": "cognito-idp:AdminUpdateUserAttributes",
"Resource": "*"
}
]
}
可以说资源应该更具体,可能仅限于您帐户中的用户池。我让你自行决定。
答案 4 :(得分:0)
当然可以。您需要使用 AWS 开发工具包。
const AWS = require('aws-sdk');
const config = require('./config');
function updateAttribute(params) {
AWS.config.update({
'region' : config.AWSConfig.region,
'accessKeyId': config.AWSConfig.accessKeyId,
'secretAccessKey': config.AWSConfig.secretAccessKey
});
let cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider();
let parameters = { UserPoolId : config.userPoolDetails.userPoolId,
Username : params.userName,
UserAttributes : [
{
'Name': params.nameOfAttribute ,
'Value': params.newValueOfAttribute
},
]}
cognitoIdentityServiceProvider.adminUpdateUserAttributes(parameters,function (err, result) {
if(err)
console.log(err);
else
console.log("Attribute updated successfully");
})
}
let params = {
userName : 'username',
nameOfAttribute : 'name',
newValueOfAttribute : 'Sachin'
}
updateAttribute(params);
您甚至可以像这样添加新属性。
答案 5 :(得分:-2)
嗯,简单的解决方案就是这样, 将此添加到“ Pre Sign-up Lambda函数”中,以从您的代码中获取提示:
// Modify an existing username...
event['request']['userAttributes']['name'] = "My_NAME";
// Add an additional attribute...
event['request']['userAttributes']['custom:sillyname'] = "ANY_NAME";
callback(null, event);
考虑到您已经为用户池添加了custom:sillyname
属性。