Итак, я создаю серверную часть с помощью AWS + ExpressJ, используя одну настройку лямбда. В 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('[email protected]'),
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,
});
}
}
При попытке создать новый экземпляр HttpAuthorizer с этим в качестве конструкции я получаю сообщение об ошибке: Аргумент типа this не может быть присвоен параметру типа Construct. В типе «AuthorizerWrapper» отсутствуют следующие свойства типа «Construct»: onValidate, onPrepare, onSynthesize.
Если я попытаюсь использовать this.scope, я получу:
Аргумент типа 'import ("PATH_TO_PROJECT/cdk/node_modules/constructs/lib/construct"). Construct' не может быть назначен параметру типа 'import ("PATH_TO_PROJECT/cdk/node_modules/@aws/cdk/core/node_modules/constructs /lib/construct").Construct'.
Это мой 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"
}
}```
идиоматический подход CDK состоял бы в том, чтобы сделать AuthorizerWrapper
подклассом Construct. См. Написание собственных конструкций в документации. Также идиоматическим является конструктор, который принимает три аргумента, как и конструкции, определенные CDK: область действия, идентификатор и свойства.
В ваших частных методах this
будет ссылаться на экземпляр AuthorizerWrapper, который является конструкцией.
interface AuthorizerWrapperProps {
api: HttpApi
}
export class AuthorizerWrapper extends Construct {
private api: HttpApi;
constructor(scope: Construct, id: string, props: AuthorizerWrapperProps) {
super(scope, id);
this.api = props.api;
this.initalize();
// ...
}
private initalize() {
this.userPool = new UserPool(this, 'JobifyUserPool', {
// ...
});
}
Н.Б. Вы получаете сообщение об ошибке, потому что, как написано, this
— это простой класс объектов JS, а не конструкция. Ваше использование this.scope
везде будет работать, но это не идиоматический CDK. Как говорится в документах:
Технически при создании экземпляра конструкции можно передать какую-то область, отличную от
this
. Практическая трудность здесь заключается в том, что вы не можете легко гарантировать, что идентификаторы, которые вы выбираете для своих конструкций, уникальны в чьей-либо области видимости. Такая практика также усложняет понимание, поддержку и повторное использование вашего кода.
Вы также должны исправить импорт HttpApi
, который в настоящее время ссылается на версию v1. В CDK v2 экспериментальные конструкции находятся в отдельных альфа-пакетах:
import { HttpApi } from "@aws-cdk/aws-apigatewayv2-alpha";
@StefanJuganaru Ваше заявление об импорте HttpApi
также неверно. Ответ отредактирован.
Это имеет большой смысл, и я только что внес это изменение в свой код. Но проблема все еще остается. Конструктор HttpAuthorizer плачет об этом: аргумент типа «это» не может быть назначен параметру типа «Конструкция».