使用 AWS Lambda、S3 和 Cloudfront 付款和 Stripe Checkout 的 CORS 问题
Posted
技术标签:
【中文标题】使用 AWS Lambda、S3 和 Cloudfront 付款和 Stripe Checkout 的 CORS 问题【英文标题】:CORS issue using AWS Lambda, S3 and Cloudfront payments with Stripe Checkout 【发布时间】:2018-05-15 13:18:34 【问题描述】:我在电子商务设置和我对 CORS 的理解方面遇到了 CORS 问题。
我有一个托管在 AWS S3 上的 React 应用程序 (Gatsby)。 CORS 配置设置为:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*.example.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
我已在 Cloudfront 发行版上进行了此设置。根据 Stripe Docs,我已将我的安全策略更改为 TLSv1.2_2018。为了让 Gatsby 工作,它需要将源设置为真实的存储桶名称:www.example.com.s3-website-eu-west-1.amazonaws.com,因为 S3 在为其提供服务时不会查找 index.html 文件干净的网址。我添加了一种将 http 更改为 https 的行为。我已将允许的 HTTP 方法设置为 GET、HEAD、OPTIONS、PUT、POST、PATCH、DELETE 和白化的原始标头。
我正在使用 Stripe 的 checkout.js 来收集卡片详细信息并使用 fetch 创建订单。这是我的功能:
async onToken (token, args)
try
let response = await fetch(process.env.STRIPE_CHECKOUT_URL,
method: 'POST',
headers:
'Access-Control-Allow-Origin': '*'
,
body: JSON.stringify(
token,
order:
currency: this.props.currency,
coupon: this.props.coupon,
items: [
type: 'sku',
parent: this.props.skuId
],
shipping:
name: args.shipping_name,
address:
line1: args.shipping_address_line1,
city: args.city,
postal_code: args.shipping_address_zip
)
)
let orderJson = await response.json()
catch(err)
alert(err)
history.push(
pathname: '/thankyou/',
state: orderId: orderJson.order.id
)
history.go()
所以,这调用了一个 AWS Lambda 函数:
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY)
module.exports.handler = (event, context, callback) =>
const requestBody = JSON.parse(event.body)
// token info
const token = requestBody.token.id
const email = requestBody.token.email
// order info
const currency = requestBody.order.currency
const items = requestBody.order.items
const shipping = requestBody.order.shipping
const coupon = requestBody.order.coupon
// Create order
return stripe.orders.create(
email: email,
coupon: coupon.id,
currency: currency,
items: items,
shipping: shipping
).then((order) =>
// Pay order with received token (from Stripe Checkout)
return stripe.orders.pay(order.id,
source: token // obtained with Stripe.js
).then((order) =>
const response =
statusCode: 200,
headers:
'Access-Control-Allow-Origin': '*'
,
body: JSON.stringify(
message: `Order processed succesfully!`,
order
)
callback(null, response)
)
).catch((err) => // Error response
console.log(err)
const response =
statusCode: 500,
headers:
'Access-Control-Allow-Origin': '*'
,
body: JSON.stringify(
error: err.message
)
callback(null, response)
)
当我测试付款时 - 我收到一个错误:
"failed to load lambda function url": Response to preflight request
doesn't pass access control check: No 'Access-Control-Allow-Origin'
header is present on the requested resource. 'https://www.example.com'
is therefore not allowed to access. The response had HTTP status code
403..."
我的 SSL 证书是为 *.example.com 设置的
这个实现安全吗?为什么它没有通过访问控制检查?
【问题讨论】:
您能否验证您的 Lambda 函数是否正在返回 Access-Control-Allow-Origin 标头?curl -s -I -X POST http://example.com/your-lambda-function-here/
【参考方案1】:
这原来是 API 网关设置的问题。启用 CORS 并从调用函数中删除标头使其工作。
【讨论】:
以上是关于使用 AWS Lambda、S3 和 Cloudfront 付款和 Stripe Checkout 的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 AWS Lambda 从 AWS S3 读取和提取巨大的 zip 文件
多个 AWS Lambda 中的 AWS::S3::Bucket LambdaConfiguration
如何从AWS Lambda检索数据并将其显示在AWS S3托管的静态网站上?