使用带有Stripe Checkout的AWS Lambda,S3和Cloudfront付款的CORS问题

时间:2017-12-01 12:21:31

标签: ssl amazon-s3 cors amazon-cloudfront gatsby

我在电子商务设置和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的行为。我已将Allowed HTTP Methods设置为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

此实施是否安全,为什么访问控制检查失败?

1 个答案:

答案 0 :(得分:1)

这证明是API网关设置的问题。启用CORS并从调用函数中删除标题使其生效。