You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用AWS Cognito确认后触发器存储用户名至DynamoDB遇Lambda报错

解决AWS Cognito触发器Lambda写入DynamoDB的主键缺失问题

我来帮你排查这个问题,从报错和代码来看,核心问题是你的Lambda代码获取的username值是undefined,导致写入DynamoDB的Item里没有有效的UserId主键,触发了ValidationException。下面分步骤解决:

1. 修正事件字段的取值逻辑

首先得明确AWS Cognito注册确认(Post Confirmation)触发器的事件结构:

  • 实际触发时,用户名的字段是event.userName(注意首字母大写的N
  • 但你用的测试事件写的是"username":"admin"(小写n),这会导致const username = event.userName取不到值,直接变成undefined

如果是测试阶段,要么修改测试事件的字段名:

{ "userName":"admin", "email":"admin@admin.com", "userId": "AD87S" }

要么在代码里兼容两种写法,避免测试和生产环境的差异:

const username = event.userName || event.username;

2. 优化Lambda Handler的异步写法

你的代码混合了async/await.then/.catch,容易导致逻辑混乱,而且Cognito触发器不需要返回HTTP响应格式,只要返回event或者null就能让Cognito继续后续流程。优化后的代码:

const AWS = require('aws-sdk'); 
const dynamodb = new AWS.DynamoDB.DocumentClient({region: 'eu-central-1'}); 

exports.handler = async (event) => { 
  console.log('Received event:', JSON.stringify(event, null, 2));
  // 兼容测试事件和实际Cognito事件的用户名字段
  const username = event.userName || event.username;
  
  if (!username) {
    console.error('Username not found in event');
    // Cognito触发器必须返回event,否则会判定执行失败
    return event;
  }

  try {
    await createMessage(username);
    console.log('Successfully wrote user data to DynamoDB');
    // 返回event让Cognito继续处理流程
    return event;
  } catch (err) {
    console.error('Error writing to DynamoDB:', err);
    // 抛出错误让Cognito捕获,或者返回event跳过错误
    throw err;
  }
}; 

function createMessage(username){ 
  const familyid = (new Date()).getTime().toString(36) + Math.random().toString(36).slice(2); 
  const params = { 
    TableName: 'eldertech', 
    Item: { 'UserId' : username, 'message' : familyid } 
  }; 
  return dynamodb.put(params).promise(); 
}

3. 验证DynamoDB表结构

确保你的eldertech表的主键是UserId(字符串类型),和代码里的字段名完全一致(DynamoDB字段名大小写敏感)。如果表的主键是其他名字(比如userId小写),也会触发这个主键缺失的报错。

4. 检查Lambda的IAM权限

最后确认执行这个Lambda的IAM角色有dynamodb:PutItem权限,虽然当前报错是主键问题,但权限不足也会导致写入失败,这是后续需要排查的次要项。

这样修改后,不管是测试事件还是实际Cognito触发,都能正确获取用户名并写入DynamoDB了。

内容的提问来源于stack exchange,提问作者David F.

火山引擎 最新活动