ses.sendmail() 给出 CORS 错误。响应中的“Access-Control-Allow-Origin”标头不得为通配符“*”。凭证模式为“包含”
Posted
技术标签:
【中文标题】ses.sendmail() 给出 CORS 错误。响应中的“Access-Control-Allow-Origin”标头不得为通配符“*”。凭证模式为“包含”【英文标题】:ses.sendmail() gives CORS error. 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*'..credentials mode is 'include' 【发布时间】:2021-05-09 08:11:36 【问题描述】:我已经坚持了 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();
);
【问题讨论】:
【参考方案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,
;
【讨论】:
以上是关于ses.sendmail() 给出 CORS 错误。响应中的“Access-Control-Allow-Origin”标头不得为通配符“*”。凭证模式为“包含”的主要内容,如果未能解决你的问题,请参考以下文章
React Ajax Request 给出 CORS 错误但返回数据
在 Firefox 上,CORS 请求给出错误“:”(冒号)
对 Url 的发布请求给出了被 cors 策略阻止的错误 [重复]