AWS CDK中HttpAuthorizer实例化类型不匹配问题求助
问题描述
我使用AWS + ExpressJS构建单Lambda架构后端,创建了辅助类AuthorizerWrapper用于初始化用户池。在该类的createAuthorizer方法中遇到两个错误:
- 使用
this作为Construct实例化HttpAuthorizer时,报错:
Argument of type 'this' is not assignable to parameter of type 'Construct'. Type 'AuthorizerWrapper' is missing the following properties from type 'Construct': onValidate, onPrepare, onSynthesize
- 改用
this.scope时,报错:
Argument of type 'import("PATH_TO_PROJECT/cdk/node_modules/constructs/lib/construct").Construct' is not assignable to parameter of type 'import("PATH_TO_PROJECT/cdk/node_modules/@aws/cdk/core/node_modules/constructs/lib/construct").Construct'.
相关代码
AuthorizerWrapper类
import { Construct } from 'constructs'; import * as cdk from 'aws-cdk-lib'; import { CfnOutput } from 'aws-cdk-lib'; import { UserPool, UserPoolClient, CfnUserPoolGroup, UserPoolEmail, } from 'aws-cdk-lib/aws-cognito'; import { IdentityPoolWrapper } from './IdentityPoolWrapper'; import { HttpApi, HttpAuthorizer } from '@aws-cdk/aws-apigatewayv2'; export class AuthorizerWrapper { private scope: Construct; private api: HttpApi; private userPool: UserPool; private userPoolClient: UserPoolClient; public authorizer: HttpAuthorizer; private identityPoolWrapper: IdentityPoolWrapper; constructor(scope: Construct, api: HttpApi) { this.scope = scope; this.api = api; this.initalize(); this.addUserPoolClient(); this.createAuthorizer(); this.initializeIdentityPoolWrapper(); this.createAdminsGroup(); } private initalize() { this.userPool = new UserPool(this.scope, 'JobifyUserPool', { userPoolName: 'JobifyUserPool', selfSignUpEnabled: true, signInAliases: { email: true, username: true, }, passwordPolicy: { minLength: 6, requireLowercase: false, requireDigits: false, requireSymbols: false, requireUppercase: false, }, userVerification: { emailSubject: 'Verify your email for Jobify', emailBody: 'Thanks for signing up to Jobify! Your verification code is {####}', }, email: UserPoolEmail.withCognito('test@fane.com'), removalPolicy: cdk.RemovalPolicy.DESTROY, }); new CfnOutput(this.scope, 'UserPoolId', { value: this.userPool.userPoolId, }); } private addUserPoolClient() { this.userPoolClient = this.userPool.addClient('JobifyUserPool-client', { userPoolClientName: 'JobifyUserPool-client', authFlows: { userPassword: true, adminUserPassword: true, custom: true, userSrp: true, }, generateSecret: false, }); new CfnOutput(this.scope, 'UserPoolClientId', { value: this.userPoolClient.userPoolClientId, }); } private createAuthorizer() { this.authorizer = new HttpAuthorizer(this, 'JobifyUserAuthorizer', { identitySource: ['$request.header.Authorization'], jwtAudience: [this.userPoolClient.userPoolClientId], jwtIssuer: this.userPool.userPoolProviderUrl, }); } private initializeIdentityPoolWrapper() { this.identityPoolWrapper = new IdentityPoolWrapper( this.scope, this.userPool, this.userPoolClient ); } private createAdminsGroup() { new CfnUserPoolGroup(this.scope, 'AdminsGroup', { groupName: 'Admins', userPoolId: this.userPool.userPoolId, roleArn: this.identityPoolWrapper.adminRole.roleArn, }); } }
package.json配置
{ "name": "cdk", "version": "0.1.0", "bin": { "cdk": "bin/cdk.js" }, "scripts": { "build": "tsc", "watch": "tsc -w", "test": "jest", "cdk": "cdk" }, "devDependencies": { "@types/aws-serverless-express": "^3.3.5", "@types/cors": "^2.8.13", "@types/express": "^4.17.17", "@types/jest": "^29.4.0", "aws-cdk-lib": "^2.73.0", "http-status-codes": "^2.2.0", "jest": "^29.5.0", "ts-jest": "^29.0.5", "typescript": "~4.9.5" }, "dependencies": { "@aws-cdk/aws-apigatewayv2": "^1.198.1", "@aws-cdk/aws-apigatewayv2-integrations": "^1.198.1", "@aws-cdk/aws-lambda": "^1.198.1", "aws-sdk": "^2.1343.0", "aws-serverless-express": "^3.4.0", "constructs": "^10.1.307", "cors": "^2.8.5", "express": "^4.18.2", "source-map-support": "^0.5.21" } }
解决方案
1. 修复CDK版本冲突
你同时使用了CDK v2(aws-cdk-lib)和CDK v1的包(@aws-cdk/aws-apigatewayv2等),二者依赖的constructs版本不兼容(v1用v9,v2用v10),导致类型不匹配错误。
修改步骤:
- 删除所有
@aws-cdk/xxx形式的依赖,CDK v2将所有服务模块整合到了aws-cdk-lib中,无需单独安装。 - 更新import语句,将
@aws-cdk/aws-apigatewayv2改为aws-cdk-lib/aws-apigatewayv2,其他v1包同理。
修改后的package.json依赖部分:
"dependencies": { "aws-sdk": "^2.1343.0", "aws-serverless-express": "^3.4.0", "constructs": "^10.1.307", "cors": "^2.8.5", "express": "^4.18.2", "source-map-support": "^0.5.21" }
2. 正确传递Construct实例
AuthorizerWrapper不是Construct的子类,所以this不能直接作为Construct参数传递。继续使用this.scope即可,版本冲突解决后这个错误会自动消失。
另外注意:原代码实例化HttpAuthorizer时缺少httpApi参数,会导致后续关联API出错,需要补上。修改后的createAuthorizer方法:
private createAuthorizer() { this.authorizer = new HttpAuthorizer(this.scope, 'JobifyUserAuthorizer', { identitySource: ['$request.header.Authorization'], jwtAudience: [this.userPoolClient.userPoolClientId], jwtIssuer: this.userPool.userPoolProviderUrl, httpApi: this.api }); }
内容的提问来源于stack exchange,提问作者Stefan Juganaru

