Cognito - Error: Invalid UserPoolId format

Cognito - Error: Invalid UserPoolId format

我正在使用 AWS CDK 创建用户池和用户池客户端。我希望能够在创建后从 lambda 访问用户池 ID 和用户池客户端 ID。我通过环境变量将这两个值传递给 lambda。这是我的代码:

import { Construct } from 'constructs';
import {
  IResource,
  LambdaIntegration,
  MockIntegration,
  PassthroughBehavior,
  RestApi,
} from 'aws-cdk-lib/aws-apigateway';
import {
  NodejsFunction,
  NodejsFunctionProps,
} from 'aws-cdk-lib/aws-lambda-nodejs';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import * as amplify from 'aws-cdk-lib/aws-amplify';

import {
  aws_s3,
  aws_ec2,
  aws_rds,
  aws_cognito,
  aws_amplify,
  Duration,
  CfnOutput,
} from 'aws-cdk-lib';

export class FrontendService extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const userPool = new aws_cognito.UserPool(this, 'userpool', {
      userPoolName: 'frontend-userpool',
      selfSignUpEnabled: true,
      signInAliases: {
        email: true,
      },
      autoVerify: { email: true },
    });

    const userPoolClient = new aws_cognito.UserPoolClient(
      this,
      'frontend-app-client',
      {
        userPool,
        generateSecret: false,
      }
    );

    const bucket = new aws_s3.Bucket(this, 'FrontendStore');

    const nodeJsFunctionProps: NodejsFunctionProps = {
      environment: {
        BUCKET: bucket.bucketName,
        DB_NAME: 'hospoFEDB',
        AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
        USER_POOL_ID: userPool.userPoolId,
        USER_POOL_CLIENT_ID: userPoolClient.userPoolClientId,
      },
      runtime: Runtime.NODEJS_14_X,
    };

    const registerLambda = new NodejsFunction(this, 'registerFunction', {
      entry: 'dist/lambda/register.js',
      memorySize: 1024,
      ...nodeJsFunctionProps,
    });

    const registerIntegration = new LambdaIntegration(registerLambda);

    const api = new RestApi(this, 'frontend-api', {
      restApiName: 'Frontend Service',
      description: 'This service serves the frontend.',
    });

    const registerResource = api.root.addResource('register');
    registerResource.addMethod('POST', registerIntegration);
  }
}

这是我的 lambda 函数以及我打算如何使用 USER_POOL_IDUSER_POOL_CLIENT_ID 环境变量:

import {
  CognitoUserPool,
} from 'amazon-cognito-identity-js';

export const handler = async (event: any, context: any) => {
  try {
    console.log(process.env.USER_POOL_ID);
    console.log(process.env.USER_POOL_CLIENT_ID);

    const userPool = new CognitoUserPool({
      UserPoolId: process.env.USER_POOL_ID as string,
      ClientId: process.env.USER_POOL_CLIENT_ID as string,
    });

    return {
      statusCode: 200,
    };
  } catch (error) {
    if (error instanceof Error) {
      const body = error.stack || (JSON.stringify(error, null, 2) as any);
      return {
        statusCode: 400,
        headers: {},
        body: JSON.stringify(body),
      };
    }
    return {
      statusCode: 400,
    };
  }
};

此设置的想法是,我将创建一个 cognito 用户池,然后客户端能够直接向下传递这些 ID。目前,如果我通过 sam local start-api 在本地 运行,它会生成以下 USER_POOL_IDFrontenduserpool87772999。如果我尝试在我的 lambda 函数的 new CognitoUserPool({... 部分使用此 ID,我会收到以下错误:

Error: Invalid UserPoolId format.

如果我部署应用程序并使用完全相同的代码从部署的环境中执行 lambda 函数,我会得到一个 USER_POOL_ID,看起来更像:us-east-1_HAjkUj9hP。这工作正常,我没有收到上述错误。

我是否应该假设我不能在本地创建用户池并且必须始终指向已部署的用户池?

Should I assume that I can not create a user pool locally and will always have to point to the deployed user pool

是的。 See the docsstart-api 创建一个模拟的本地 API 端点和 Lambda 用于本地测试。它不部署或模拟其他资源。

您可以通过使用 --env-vars 标志传递 JSON file with the deployed physical values 来引用以前部署的 AWS 资源。