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

如何在Lambda函数中验证Cognito会话以获取DynamoDB数据?

嘿,刚好有经验处理这个场景!你已经用Amplify搞定了Cognito用户认证,现在要在Lambda里验证会话有效性,其实核心是验证Cognito返回的ID Token或者Access Token的合法性,下面给你两种靠谱的实现方式:

方法一:用AWS SDK调用Cognito官方API验证(简单直接)

这种方式最省心,AWS会帮你处理所有验证逻辑(比如令牌签名、过期时间、权限校验等),你只需要调用CognitoIdentityServiceProvider的getUser方法,传入用户的Access Token就行。

步骤:

  1. 前端传令牌到Lambda:Amplify认证成功后,你可以通过Auth.currentSession()拿到会话中的accessToken.jwtToken,把它放在请求的Authorization头里(格式:Bearer <你的access-token>),通过API Gateway或者其他方式传给Lambda。
  2. Lambda中编写验证逻辑:
    先确保Lambda的IAM角色有cognito-idp:GetUser的权限,然后用AWS SDK调用API:
const AWS = require('aws-sdk');
const cognito = new AWS.CognitoIdentityServiceProvider({ region: '你的AWS区域' });

exports.handler = async (event) => {
  // 从请求头中提取Access Token
  const authHeader = event.headers.Authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return {
      statusCode: 401,
      body: JSON.stringify('未提供有效令牌')
    };
  }
  const accessToken = authHeader.split(' ')[1];
  
  try {
    // 调用Cognito API验证令牌并获取用户信息
    const user = await cognito.getUser({ AccessToken: accessToken }).promise();
    // 令牌有效,继续处理业务逻辑
    return {
      statusCode: 200,
      body: JSON.stringify({ message: '会话有效', username: user.Username })
    };
  } catch (error) {
    // 令牌无效(过期、篡改、非法等),返回401
    return {
      statusCode: 401,
      body: JSON.stringify('会话无效:' + error.message)
    };
  }
};

如果令牌无效,这个API会抛出NotAuthorizedException或ExpiredTokenException等明确错误,你可以根据错误类型返回对应提示。

方法二:手动验证JWT令牌(性能更优)

Cognito的ID Token是标准JWT格式,你可以手动验证它的签名、过期时间、受众(Audience)等信息,这种方式不需要调用AWS服务,响应更快,适合高并发场景。

步骤:

  1. 获取Cognito公钥:Cognito会把公钥放在固定地址:https://cognito-idp.<你的区域>.amazonaws.com/<你的用户池ID>/.well-known/jwks.json,建议缓存这些公钥,避免每次请求都拉取。
  2. 用JWT库验证令牌:比如用jsonwebtoken+jwks-rsa库(需要在Lambda层或打包时包含这些依赖):
const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');

// 初始化JWKS客户端,用于从Cognito获取公钥
const client = jwksClient({
  jwksUri: 'https://cognito-idp.<你的区域>.amazonaws.com/<你的用户池ID>/.well-known/jwks.json'
});

// 封装获取公钥的函数
function getSigningKey(header, callback) {
  client.getSigningKey(header.kid, function(err, key) {
    const signingKey = key.publicKey || key.rsaPublicKey;
    callback(null, signingKey);
  });
}

exports.handler = async (event) => {
  const authHeader = event.headers.Authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return { statusCode: 401, body: JSON.stringify('未提供有效令牌') };
  }
  const idToken = authHeader.split(' ')[1];
  
  return new Promise((resolve, reject) => {
    jwt.verify(idToken, getSigningKey, {
      audience: '<你的Cognito客户端ID>', // 必须和Amplify配置的clientId一致
      issuer: 'https://cognito-idp.<你的区域>.amazonaws.com/<你的用户池ID>',
      algorithms: ['RS256'] // Cognito固定用RS256签名
    }, function(err, decoded) {
      if (err) {
        resolve({ statusCode: 401, body: JSON.stringify('会话无效:' + err.message) });
      } else {
        // 令牌有效,decoded中包含用户的username、邮箱等信息
        resolve({
          statusCode: 200,
          body: JSON.stringify({ message: '会话有效', userInfo: decoded })
        });
      }
    });
  });
};

两种方法对比:

  • 方法一:简单易维护,无需处理JWT细节,还能顺便获取用户属性信息,但会调用AWS API,有轻微延迟和极低成本。
  • 方法二:性能更好,无额外API调用,但需要处理公钥缓存、JWT验证细节,依赖第三方库。

根据你的业务场景选择就行啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:36:08