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

求助:实现AWS Cognito预认证Lambda触发器(查询外部DB用户订阅)

AWS Cognito预认证Lambda触发器查询外部数据库示例

以下是Node.js版本的Lambda示例,用于在Cognito预认证阶段查询外部数据库(以MySQL为例)验证用户订阅状态:

1. 前提准备

  • 确保Lambda函数配置了访问目标数据库的权限:
    • 将Lambda部署到与数据库同VPC的子网中
    • 安全组允许Lambda访问数据库端口(如MySQL的3306)
    • 为Lambda添加对应IAM权限(若用IAM认证数据库需额外配置)
  • 在Lambda层或代码包中包含数据库驱动(如mysql2)

2. Lambda代码示例

const mysql = require('mysql2/promise');

// 数据库连接配置(建议用环境变量存储敏感信息)
const dbConfig = {
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  port: 3306
};

// 创建连接池(避免每次请求新建连接)
const pool = mysql.createPool(dbConfig);

exports.handler = async (event) => {
  // 从Cognito事件中提取待认证用户标识(如用户名或邮箱,依用户池配置而定)
  const userId = event.request.userName; // 也可使用 event.request.userAttributes.email
  
  let connection;
  try {
    // 获取数据库连接
    connection = await pool.getConnection();
    
    // 查询用户订阅信息
    const [rows] = await connection.execute(
      'SELECT subscription_status, subscription_expiry FROM user_subscriptions WHERE user_id = ?',
      [userId]
    );
    
    if (rows.length === 0) {
      // 用户无订阅记录,阻止认证
      return {
        response: {
          failAuthentication: true,
          message: "未找到用户订阅信息,无法完成认证"
        }
      };
    }
    
    const userSubscription = rows[0];
    if (userSubscription.subscription_status !== 'active' || new Date(userSubscription.subscription_expiry) < new Date()) {
      // 订阅已过期或未激活,阻止认证
      return {
        response: {
          failAuthentication: true,
          message: "订阅已过期或未激活,请重新订阅"
        }
      };
    }
    
    // 订阅有效,允许认证,可添加自定义属性到用户会话
    return {
      response: {
        allowAuthentication: true,
        // 可选:添加自定义属性到Cognito用户会话
        claimsOverrideDetails: {
          claimsToAddOrOverride: {
            subscription_level: 'premium',
            subscription_expiry: userSubscription.subscription_expiry
          }
        }
      }
    };
    
  } catch (error) {
    console.error('查询订阅信息失败:', error);
    // 数据库查询出错时,阻止认证并返回提示
    return {
      response: {
        failAuthentication: true,
        message: "认证过程中出现错误,请稍后重试"
      }
    };
  } finally {
    // 释放连接回池
    if (connection) connection.release();
  }
};

3. 关键注意事项

  • 敏感信息存储:不要硬编码数据库账号密码,用Lambda环境变量配置DB_HOST、DB_USER等参数
  • 连接池优化:使用连接池而非每次新建连接,避免数据库连接耗尽
  • 响应格式要求:必须返回符合Cognito规范的结构,allowAuthentication或failAuthentication二选一
  • 错误处理:捕获数据库查询异常,避免Lambda执行报错导致Cognito认证流程中断
  • 用户标识匹配:确保查询用的user_id与Cognito中的用户标识(如用户名、邮箱)一致,需提前在外部数据库同步该标识

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 07:25:14