You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为所有Cognito身份(含桌面、移动端)附加IoT策略?

问题根因

你遇到的报错本质是触发场景和官方文档描述的场景不匹配:

官方文档提到的context.cognito_identity_id字段存在的前提是:Lambda函数由用户持Cognito身份池颁发的凭证直接调用。而你现在用的是Cognito用户池的Post Confirmation触发器,这个场景下Lambda是由Cognito服务内部调用的,调用主体不是用户身份,因此context对象完全不会携带identity相关字段,自然会报属性不存在的错误。

另外你代码里还有一个隐藏问题:IoT的attachPolicy接口的policyName参数要求传入IoT策略的名称字符串,不能传策略ARN,否则也会调用失败。

最优实现方案(适配所有端用户)

不需要依赖Lambda context属性,也不用区分桌面/移动端,推荐直接使用Cognito身份池的同步触发器实现,流程如下:

  1. 打开你的Cognito身份池配置,找到「同步触发器」配置项,绑定你的Lambda函数
  2. 当任意端的用户首次在身份池中创建身份时,Lambda会被触发,event对象中会直接携带identityId字段,无需自行查询
  3. 给Lambda执行角色添加iot:AttachPolicy权限

修改后的Lambda代码示例:

const AWS = require('aws-sdk');
const iot = new AWS.Iot();

// 替换为你自己创建的IoT策略名称,注意不是ARN
const IOT_POLICY_NAME = '你的IoT策略名称';

exports.handler = async function(event, context) {
    // 直接从触发器event中获取身份ID,所有端用户触发时都有这个字段
    const target = event.identityId;
    
    await iot.attachPolicy({ 
        target, 
        policyName: IOT_POLICY_NAME 
    }).promise();

    // 身份池触发器要求返回event对象继续后续流程,不要返回自定义响应
    return event;
};
如果你坚持要使用用户池Post Confirmation触发器实现

需要先完成前置配置:确保你的Cognito用户池已经作为身份提供者关联到目标身份池。
实现逻辑是从Post Confirmation触发器的event中提取用户属性,调用Cognito Identity接口查询对应的身份ID,再附加策略:

  1. 给Lambda执行角色添加两个权限:cognito-identity:GetId、iot:AttachPolicy
  2. 修改代码如下:
const AWS = require('aws-sdk');
const iot = new AWS.Iot();
const cognitoIdentity = new AWS.CognitoIdentity();

// 替换为你自己的配置
const IOT_POLICY_NAME = '你的IoT策略名称';
const IDENTITY_POOL_ID = '你的区域:xxxx-xxxx-xxxx-xxxx';
const USER_POOL_ID = '你的区域_xxxxxxxxx';
const USER_POOL_PROVIDER = `cognito-idp.${USER_POOL_ID.split('_')[0]}.amazonaws.com/${USER_POOL_ID}`;

exports.handler = async function(event, context) {
    // 从触发器event中获取用户唯一标识sub和最新的ID令牌
    const userSub = event.request.userAttributes.sub;
    const userIdToken = event.request.userAttributes.idToken; // 部分触发器版本需要自行从event中提取ID令牌
    
    // 查询对应用户的身份池ID
    const idResp = await cognitoIdentity.getId({
        IdentityPoolId: IDENTITY_POOL_ID,
        Logins: {
            [USER_POOL_PROVIDER]: userIdToken
        }
    }).promise();
    
    const target = idResp.IdentityId;
    await iot.attachPolicy({ 
        target, 
        policyName: IOT_POLICY_NAME 
    }).promise();

    // Post Confirmation触发器要求返回event对象
    return event;
};

如果你的Post Confirmation触发器event中无法获取到用户ID令牌,建议优先使用身份池触发器方案。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 22:27:02