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

Node.js Lambda获取Cognito Token调用接口返回401问题求助

问题描述

我在Node.js Lambda函数中开发了从AWS获取Token的代码,成功获取Token后调用任意接口均返回401 Unauthorized。

通过JWT解码后,Lambda获取的Token内容如下:

{
  "sub": "*****",
  "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-*****",
  "client_id": "*****",
  "origin_jti": "*****",
  "event_id": "******",
  "token_use": "access",
  "scope": "aws.cognito.signin.user.admin",
  "auth_time": 1719906953,
  "exp": 1719910553,
  "iat": 1719906953,
  "jti": "*****",
  "username": "*****"
}

而通过Postman获取的Token解码后内容如下:

{
  "sub": "*****",
  "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-*****",
  "version": 2,
  "client_id": "*****",
  "origin_jti": "*****",
  "token_use": "access",
  "scope": "aws.cognito.signin.user.admin phone openid mpfapi/fullaccess email",
  "auth_time": 1719917974,
  "exp": 1719921574,
  "iat": 1719917974,
  "jti": "*****",
  "username": "*****"
}

Lambda代码获取的Token调用接口返回401,Postman获取的Token可正常使用。我的Node.js代码如下:

const getSecretHash = (username, clientId, clientSecret) => {
    return crypto.createHmac('SHA256', clientSecret)
        .update(username + clientId)
        .digest('base64');
};
const authenticateUser = async (username, password) => {
    const client = new CognitoIdentityProviderClient({ region: RYSEregion });
    const secretHash = getSecretHash(username, poolData.ClientId, poolData.ClientSecret);

    const params = {
        AuthFlow: 'USER_PASSWORD_AUTH',
        AuthParameters: {
            'USERNAME': username,
            'PASSWORD': password,
            'SECRET_HASH': secretHash
        },
        ClientId: poolData.ClientId
    };

    try {
        const command = new InitiateAuthCommand(params);
        const response = await client.send(command);
        return response.AuthenticationResult.IdToken;
    } catch (error) {
        console.error("Error: ", error);
        throw error;
    }
};

Postman配置:

  • 认证类型:OAuth 2.0
  • 授权类型:Authorization code

我推测问题是Postman通过重定向触发Cognito托管UI认证,Lambda用的是另一种认证方式,导致Token权限范围不一致,但找不到Cognito中添加权限范围的配置。请问我遗漏了什么?


问题原因与解决方案

核心原因

Lambda代码使用的USER_PASSWORD_AUTH认证流默认仅返回包含aws.cognito.signin.user.admin基础权限的Token,而Postman采用的Authorization Code流会自动请求并返回Cognito客户端配置中已启用的所有授权范围,这是两者scope字段差异的直接原因,也是401错误的核心诱因。

解决步骤

1. 在InitiateAuth请求中指定所需Scope

修改Lambda代码的AuthParameters,添加SCOPE参数,明确声明需要的权限范围(匹配Postman中的scope内容):

const params = {
    AuthFlow: 'USER_PASSWORD_AUTH',
    AuthParameters: {
        'USERNAME': username,
        'PASSWORD': password,
        'SECRET_HASH': secretHash,
        // 添加指定权限范围
        'SCOPE': 'aws.cognito.signin.user.admin phone openid mpfapi/fullaccess email'
    },
    ClientId: poolData.ClientId
};

2. 确认Cognito客户端已启用对应Scope

登录AWS控制台,进入目标Cognito用户池:

  • 找到对应的应用客户端,进入「应用客户端设置」页面
  • 确保「已授权的OAuth范围」中勾选了你需要的phone、openid、email以及自定义的mpfapi/fullaccess范围
  • 确认「允许的OAuth流」中已启用USER_PASSWORD_AUTH(若未开启需勾选)

3. 修正返回的Token类型

你的代码当前返回的是IdToken,但从JWT的token_use字段来看,接口需要的是AccessToken(用于调用受保护接口的凭证,IdToken主要用于身份信息识别),需修改返回值:

// 替换原返回语句,返回AccessToken而非IdToken
return response.AuthenticationResult.AccessToken;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:04:51