为 SAM 配置 CORS。 API 适用于邮递员,但不适用于 angular

Configuring CORS for SAM. API works with postman, but not angular

我在 angular 应用程序中使用邮递员使用的相同端点注册用户时遇到问题。 Postman 工作正常并且用户出现在 cognito 用户池中没问题,但是如果我尝试通过我的 angular 应用程序中的注册页面注册用户,那么我会收到 CORS 错误

当我查看 API 网关时,我注意到不同端点中没有选项部分,所以这可能是个问题。

此外,当我部署 SAM 时,我发现没有设置授权,所以这也可能是一个因素。虽然不确定。如何配置我的 SAM 模板以使 CORS 与应用程序一起使用而不仅仅是邮递员?感谢您的帮助!

SAM 模板

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: REST API using SAM

Globals:
  Function:
    Runtime: nodejs12.x
    Environment:
      Variables:
        TABLE_NAME: !Ref Table
    MemorySize: 128
    Timeout: 5

Resources:
  Table:
    Type: AWS::Serverless::SimpleTable
    Properties:
      PrimaryKey:
        Name: userid
        Type: String
      ProvisionedThroughput:
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1

  ConfirmUser:
    Type: AWS::Serverless::Function
    Properties:
      Handler: confirm.handler
      Events:
        GetUser:
          Type: Api
          Properties:
            Path: /confirm
            Method: post

  RegisterUser:
    Type: AWS::Serverless::Function
    Properties:
      Handler: register.handler
      Policies: AmazonDynamoDBFullAccess
      Events:
        GetUser:
          Type: Api
          Properties:
            Path: /register
            Method: post

  LoginUser:
    Type: AWS::Serverless::Function
    Properties:
      Handler: login.handler
      Events:
        GetUser:
          Type: Api
          Properties:
            Path: /login
            Method: post

register.js

const AWS = require('aws-sdk');
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
global.fetch = require('node-fetch');

const UserPoolId = "<my user poolId>"
const ClientId = "<my client id>"

const poolData = {
    UserPoolId,
    ClientId
}

AWS.config.update({
    region: 'us-east-1'
})

async function registerUser(json) {
    const {
        email,
        password
    } = json

    return new Promise((resolve, reject) => {
        let attributeList = []

        attributeList.push(new AmazonCognitoIdentity.CognitoUserAttribute({ Name: "email", Value: email }));


        const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

        userPool.signUp(email, password, attributeList, null, function (err, result) {
            if (err) {
                return resolve({
                    statusCode: 500,
                    err
                })
            }

            resolve({
                statusCode: 200,
                message: 'User successfully registered'
            })
        })
    })
}

exports.handler = async function (event, context, callback) {
    console.log("EVENT BODY", event.body)
    const json = JSON.parse(event.body)
    let result;
    let response;
    try {
        result = await registerUser(json);

        response = {
            statusCode: 200,
            body: JSON.stringify('User registered successfully'),
            headers: {
                "Access-Control-Allow-Origin": "*", // Required for CORS support to work
                "Access-Control-Allow-Credentials": true // Required for cookies, authorization headers with HTTPS 
            },
        };
    } catch (e) {
        response = {
            statusCode: 500,
            body: JSON.stringify('Failed to register user'),
            headers: {
                "Access-Control-Allow-Origin": "*", // Required for CORS support to work
                "Access-Control-Allow-Credentials": true // Required for cookies, authorization headers with HTTPS 
            },
        };
    }

    return response;

}

我们需要一个 OPTIONS 方法返回三个以下 headers 以便浏览器允许 CORS

Access-Control-Allow-Headers should contain all headers
Access-Control-Allow-Methods should contain all methods
Access-Control-Allow-Origin should contain the host or '*'

将以下模板添加到 SAM Globals 将为指向 Mock Integration 的每个方法添加必要的 OPTIONS 方法。

所有额外的 Headers 如果有的话应该添加到 AllowHeaders

Globals:
  Api:
    Cors:
      AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"
      AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
      AllowOrigin: "'*'"
      AllowCredentials: "'*'"