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

如何用AWS CDK为RestApi实现Cognito与IAM双授权?

在AWS CDK中为RestApi同时配置Cognito与IAM授权

问题背景

我正在重构现有Amplify项目,原项目采用AppSync搭配Cognito和IAM授权模式。现在希望通过AWS CDK构建所有资源,并将AppSync替换为API Gateway,需要实现RestApi同时支持Cognito(认证用户)和IAM(访客访问)双授权模式。

AppSync中可以直接指定双授权模式,示例代码如下:

const api = new GraphqlApi(this, 'TodoTestAPI', {
  name: 'TodoTestAPI',
  schema: Schema.fromAsset(path.join(__dirname, 'schema.graphql')),
  authorizationConfig: {
    defaultAuthorization: {
      authorizationType: AuthorizationType.USER_POOL,
      userPoolConfig: {
        userPool,
      },
    },
    additionalAuthorizationModes: [
      {
        authorizationType: AuthorizationType.IAM,
      },
    ],
  },
});

我当前的RestApi CDK代码如下,目前仅配置了IAM授权:

const api = new RestApi(this, `RestApi`, {
      defaultMethodOptions: {
            authorizationType: AuthorizationType.IAM,
        },
      defaultCorsPreflightOptions: {
            allowOrigins: Cors.ALL_ORIGINS,
            allowMethods: Cors.ALL_METHODS,
        },
      cloudWatchRole: true,
  });

实现方案

API Gateway的RestApi与AppSync的授权配置逻辑不同:AppSync是在API层面统一设置默认和附加授权模式,而RestApi需要在方法层面配置多授权类型。以下是具体实现步骤:

1. 准备Cognito资源(若未创建)

首先确保你已有Cognito用户池和用户池客户端,若没有则通过CDK创建:

import { UserPool, UserPoolClient } from 'aws-cdk-lib/aws-cognito';

// 创建Cognito用户池
const userPool = new UserPool(this, 'MyUserPool', {
  userPoolName: 'MyAppUserPool',
  // 根据你的需求配置用户池属性,比如验证方式、密码规则等
});

// 创建用户池客户端
const userPoolClient = new UserPoolClient(this, 'MyUserPoolClient', {
  userPool,
  clientName: 'MyAppClient',
});

2. 创建Cognito授权器

在API Gateway中,需要先创建Cognito用户池授权器,用于验证Cognito生成的ID Token:

import { CognitoUserPoolsAuthorizer } from 'aws-cdk-lib/aws-apigateway';

const cognitoAuthorizer = new CognitoUserPoolsAuthorizer(this, 'CognitoAuthorizer', {
  cognitoUserPools: [userPool],
  authorizerName: 'CognitoUserPoolAuthorizer',
});

3. 配置RestApi支持双授权

你可以选择两种方式配置:全局默认双授权,或者为单个方法单独配置。

方式一:全局默认双授权(所有方法默认支持IAM+Cognito)

在创建RestApi时,通过defaultMethodOptions设置默认授权类型为IAM,并添加Cognito作为额外授权类型,同时指定Cognito授权器:

import { RestApi, AuthorizationType, Cors } from 'aws-cdk-lib/aws-apigateway';

const api = new RestApi(this, `RestApi`, {
  defaultMethodOptions: {
    authorizationType: AuthorizationType.IAM, // 默认启用IAM授权(访客访问)
    additionalAuthorizationTypes: [AuthorizationType.COGNITO], // 添加Cognito授权类型
    authorizer: cognitoAuthorizer, // 指定Cognito授权器
  },
  defaultCorsPreflightOptions: {
    allowOrigins: Cors.ALL_ORIGINS,
    allowMethods: Cors.ALL_METHODS,
  },
  cloudWatchRole: true,
});

方式二:为单个方法单独配置双授权

如果仅部分方法需要双授权,可以在创建方法时覆盖默认配置:

// 先创建基础RestApi(默认仅IAM授权)
const api = new RestApi(this, `RestApi`, {
  defaultMethodOptions: {
    authorizationType: AuthorizationType.IAM,
  },
  defaultCorsPreflightOptions: {
    allowOrigins: Cors.ALL_ORIGINS,
    allowMethods: Cors.ALL_METHODS,
  },
  cloudWatchRole: true,
});

// 创建资源和方法,为该方法添加Cognito授权
const todosResource = api.root.addResource('todos');

// 假设已创建Lambda集成(替换为你的实际集成,比如Lambda、HTTP等)
import { LambdaIntegration } from 'aws-cdk-lib/aws-apigateway';
import { Function, Runtime, Code } from 'aws-cdk-lib/aws-lambda';

const todoLambda = new Function(this, 'TodoLambda', {
  runtime: Runtime.NODEJS_20_X,
  handler: 'index.handler',
  code: Code.fromAsset('lambda'),
});

// 为GET方法配置双授权
todosResource.addMethod('GET', new LambdaIntegration(todoLambda), {
  authorizationType: AuthorizationType.IAM,
  additionalAuthorizationTypes: [AuthorizationType.COGNITO],
  authorizer: cognitoAuthorizer,
});

关键说明

  • API Gateway允许一个方法同时支持多种授权类型,请求只要通过其中一种授权验证即可访问。
  • IAM授权依赖于AWS签名的请求(如通过Amplify的Auth.signIn后获取的凭证,或访客的匿名角色)。
  • Cognito授权依赖于Cognito用户池生成的ID Token,需要在请求头中携带Authorization: Bearer <ID_TOKEN>。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:07:52