【问题标题】:ses.sendmail() gives CORS error. 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*'..credentials mode is 'include'ses.sendmail() 给出 CORS 错误。响应中的“Access-Control-Allow-Origin”标头不得为通配符“*”。凭证模式为“包含”
【发布时间】:2023-03-07 09:07:01
【问题描述】:

我已经坚持了 4 天了。我真的需要一些见解。

我在 AWS 上部署了一个无服务器 express 应用程序。我从 S3 为我的前端提供服务,从 lambda 提供后端服务。 API 网关具有代理,如下面的 serverless.yml 所示。

我还使用 Cloudfront 将我的域 (https://my.domain.com.au) 映射到 S3 存储桶原始 URL。

正常的 GET POST PUT DELETE 请求工作正常。但是当我尝试从 Lambda 访问任何其他 AWS 服务时,我会收到以下 CORS 错误。

Access to XMLHttpRequest at 'https://0cn0ej4t5w.execute-api.ap-southeast-2.amazonaws.com/prod/api/auth/reset-password' from origin 'https://my.domain.com.au' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

我的用例是从我尝试使用的应用发送邮件。

ses.sendEmail(params).promise();

这给了我同样的错误。所以我尝试通过 lambda 调用它,同样的错误。现在我正在尝试将邮件内容推送到 S3 并使用触发器从 lambda 发送邮件,但这给了我同样的错误。

问题似乎不在代码上,因为它在本地环境中完美运行。但是,我不想留下任何石头。

由于我的 lambda 在 VPC 中,我使用了互联网网关并尝试设置私有链接。

无服务器.yml

service: my-api

# plugins 
plugins:
  - serverless-webpack
  - serverless-offline
  - serverless-dotenv-plugin

# custom for secret inclusions
custom:
  stage: ${opt:stage, self:provider.stage}
  serverless-offline:
    httpPort: 5000
  webpack:
    webpackConfig: ./webpack.config.js
    includeModules: # enable auto-packing of external modules
      forceInclude:
        - mysql
        - mysql2 
        - passport-jwt
        - jsonwebtoken
        - moment
        - moment-timezone
        - lodash

# provider
provider:
  name: aws
  runtime: nodejs12.x
  # you can overwrite defaults here
  stage: prod
  region: ${env:AWS_REGION_APP}
  timeout: 10
  iamManagedPolicies:
    - 'arn:aws:iam::777777777777777:policy/LambdaSESAccessPolicy'
  vpc:
    securityGroupIds:
      - ${env:AWS_SUBNET_GROUP_ID}
    subnetIds:
      - ${env:AWS_SUBNET_ID1}
      - ${env:AWS_SUBNET_ID2}
      - ${env:AWS_SUBNET_ID3}
  environment:
    /// env variables (hidden)
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - s3:*
        - ses:*
        - lambda:*
      Resource: '*'

# functions
functions:
  app:
    handler: server.handler
    events:
      - http:
          path: /
          method: ANY
      - http:
          path: /{proxy+}
          method: ANY
          cors:
            origin: ${env:CORS_ORIGIN_URL}
            allowCredentials: true
            headers: 'Access-Control-Allow-Origin, Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization'
            method: ANY

# you can add CloudFormation resource templates here
resources:
  # API Gateway Errors
  - ${file(resources/api-gateway-errors.yml)}
  # VPC Access for RDS
  - ${file(resources/lambda-vpc-access.yml)}

我也配置了响应头:

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", process.env.CORS_ORIGIN_URL);
    res.header("Access-Control-Allow-Headers", "Access-Control-Allow-Origin, Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization");
    res.header("Access-Control-Allow-Credentials", "true");
    res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT,DELETE");
    next();
});

【问题讨论】:

    标签: amazon-s3 aws-lambda cors amazon-cloudfront amazon-ses


    【解决方案1】:

    我实际上和你有同样的错误,但我已经弄清楚了。

    我只是粘贴我的代码,因为你没有显示你的 lambda 函数是什么样子的。

    我也知道已经过去了两周...所以希望这对将来的人有所帮助。

    CORS 错误是服务器端的,我相信您知道。 AWS SES 的问题是您必须正确处理 lambda,否则即使您有正确的标头,它也会给您一个 cors 错误。

    首先要做的事情...我认为您的 api 网关中没有 OPTIONS 方法...尽管我不确定是否可以替代任何方法。

    第二个是我的代码: 我检查我得到的 http 方法,然后我根据它做出响应。我收到一个帖子事件,正文中有一些细节。您可能希望将 finally 块更改为其他内容。 OPTIONS 对 CORS 很重要,它让浏览器知道可以发送 POST 请求(或者至少我是这么认为的)

    var ses = new AWS.SES();
    
    var RECEIVER = 'receiver@gmail.com';
    var SENDER = 'sender@gmail.com';
    
    exports.handler = async(event) => {
    
      let body;
      let statusCode = '200';
      const headers = {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET,DELETE,POST,PATCH,OPTIONS',
        'Access-Control-Allow-Credentials': true,
        'Access-Control-Allow-Headers': 'access-control-allow-credentials,access-control-allow-headers,access-control-allow-methods,Access-Control-Allow-Origin,authorization,content-type',
        'Content-Type': 'application/json'
      };
      console.log(event);
    
      try {
        switch (event.httpMethod) {
          case 'POST':
            event = JSON.parse(event.body);
            var params = {
              Destination: {
                ToAddresses: [
                  RECEIVER
                ]
              },
              Message: {
                Body: {
                  Html: {
                    Data: html(event.name, event.phone, event.email, event.message), // 'Name: ' + event.name + '\nPhone: ' + event.phone + '\nEmail: ' + event.email + '\n\nMessage:\n' + event.message,
                    Charset: 'UTF-8'
                  }
                },
                Subject: {
                  Data: 'You Have a Message From ' + event.name,
                  Charset: 'UTF-8'
                }
              },
              Source: SENDER
            };
            await ses.sendEmail(params).promise();
            break;
          case 'OPTIONS':
            statusCode = '200';
            body = "OK";
            break;
          default:
            throw new Error(`Unsupported method "${event.httpMethod}"`);
        }
      }
      catch (err) {
        statusCode = '400';
        body = err.message;
      }
      finally {
        body = "{\"result\": \"Success\"}"
      }
     
      console.log({
        statusCode,
        body,
        headers,
      })
      return {
        statusCode,
        body,
        headers,
      };
    
    }
    

    【讨论】:

      猜你喜欢
      • 2018-07-31
      • 2018-12-16
      • 2020-09-21
      • 2018-11-09
      • 2019-02-07
      • 2021-11-18
      • 1970-01-01
      • 2016-05-13
      • 2018-07-29
      相关资源
      最近更新 更多