如何在firebase函数环境下解决CORS?

cetgtptt  于 2023-04-07  发布在  其他
关注(0)|答案(4)|浏览(185)

我遇到了CORS问题。在我的functions/index.js中,我有:

const cors = require('cors')({
  origin: true
});

我的端点是https://sis-t.redsys.es:25443/sis/realizarPago .我需要做一个POST到这个url与appropriate参数从客户端,这是外部的firebase环境.我也有正确的计划,以允许外部网络,但使请求到一个不同的地址比源之一,触发CORS问题:

我读到过你只需要修改头部,但这只适用于你向自己的服务器发出请求的情况。当你执行http.onRequest()时,你可以在函数内部使用中间件,但当你向外部服务器发出POST时会发生什么呢?
以下是执行POSTaxios函数:

cardPay: function () {
  this.cardProcess = true
    axios({
      method: 'post',
      url: 'https://us-central1-cutre-windrider.cloudfunctions.net/cardPay',
      data: {
        verifiedUserLogged: this.userLogged.uid,
        cart: this.cartItemList,
        finalPrice: this.serverPrice,
        deliveryInfo: this.userLogged.deliveryAdress,
        name: this.userLogged.displayName || false,
        email: this.userLogged.email
      }
    })
    .then(response => {
      this.requestData = response
      this.redsysRedirect(response.data.data)
    })
    .catch(console.log)
    },
redsysRedirect: function (data) {
  axios.post('https://sis-t.redsys.es:25443/sis/realizarPago', {
    'Ds_SignatureVersion': 'HMAC_SHA256_V1',
    'Ds_MerchantParameters': data.merchantParameters,
    'Ds_Signature': data.signature
  }).then(console.log).catch(console.log)

以下是服务器端函数:

exports.cardPay = functions.https.onRequest((req, res) => {
  return cors(req, res, () => {
    const cart = req.body.cart
    const user = req.body.verifiedUserLogged
    const key = admin.database().ref(`sales/${user}`).push().key
    processCart(cart).then(result => {
      console.info(createPayment(result, key))
      return res.json({ "data": createPayment(result, key) }).end()
    }).catch(console.log)
  })
})

function processCart(cart) {
  return new Promise((resolve, reject) => {
    Promise.all(cart.map(i => switcher(i)))
      .then(prices => resolve(
        prices.reduce(
          (finalPrice, price) => price + finalPrice, 0)
      )).catch(console.log)
  });
}

function switcher(item) {
  switch (item.destiny) {
    case 'bookedLessons':
        return lessonPrice(item.name, item.index)
      case 'bookedRentals':
        return rentalPrice(item.id, item.index, item.insurancePurchased, item.insuranceId)
      case 'bookedLodgins':
        return item.reservationData ? roomPriceWithReservation(item.id, item.quantity, item.persons, item.reservationData) : roomPriceNoReservation(item.id, item.quantity, item.persons)
      case 'deliveries':
        return productPrice(item.id, item.quantity)
      case 'bookedCar':
        return carPrice(item.id, item.index)
      case 'bookedStorage':
        return storagePrice(item.index)
      case 'bookedTransportation':
        return transportationPrice(item.id, item.index, item.persons, item.roundTrip)
      case 'bookedDoublePack':
        return doublePack(item.id, item.persons)
      case 'bookedTriplePack':
        return triplePack(item.id, item.persons)
      default:
        break
  }
}

function createPayment(total, orderId) {
  let redsys = new Redsys();
  let mParams = {
      "DS_MERCHANT_AMOUNT":total.toString(),
      "DS_MERCHANT_ORDER":orderId,
      "DS_MERCHANT_MERCHANTCODE":   "025988262",
      // "DS_MERCHANT_MERCHANTCODE":tpvInfo.fucCode,
      "DS_MERCHANT_CURRENCY":"978",
      // "DS_MERCHANT_CURRENCY":tpvInfo.currency,
      "DS_MERCHANT_TRANSACTIONTYPE":"0",
      // "DS_MERCHANT_TRANSACTIONTYPE":tpvInfo.transaction_type,
      "DS_MERCHANT_TERMINAL":   "001",
      // "DS_MERCHANT_TERMINAL":tpvInfo.terminal,
      "DS_MERCHANT_MERCHANTURL":'http://localhost:8080',
      "DS_MERCHANT_URLOK":'http://localhost:8080/home?foo=true',
      "DS_MERCHANT_URLKO":'http://localhost:8080/home?foo=false'
  };
  return  {signature: redsys.createMerchantSignature(/* tpvInfo.secret */   "sq7HjrUOBfKmC576ILgskD5srU870gJ7", mParams) , merchantParameters: redsys.createMerchantParameters(mParams), raw: mParams};
}
ldioqlga

ldioqlga1#

对于将来会遇到这个问题的人(或我未来的自己):
如果您已经使用cors包配置了CORS,并且您认为您配置正确,并且在浏览器控制台中仍然有CORS错误,请查看这篇文章:
https://haha.world/firebase-cors/
基本上,这是一个误导性的错误从谷歌云函数返回,而实际上错误是在你的代码逻辑(这是完全无关的CORS在所有)
因此,修复此错误的第一步是检查Google Cloud Functions日志(或Firebase Cloud Functions日志),以查看您的函数是否因代码中的任何错误而崩溃。然后修复它。

注意:对于没有我上面描述的问题的人,您可以查看其他答案,或查看这些资源:

  1. https://expressjs.com/en/resources/middleware/cors.html
  2. https://firebase.google.com/docs/functions/http-events#using_existing_express_apps
jxct1oxe

jxct1oxe2#

在Firebase Function响应标头中,您可以显式允许所有来源:

exports.handler = ((req, res) => {
    res.set({ 'Access-Control-Allow-Origin': '*' }).sendStatus(200)
})

或者你可以修改它只允许特定的起源。这是我过去用Firebase函数解决CORS问题的一般方法。

mwngjboj

mwngjboj3#

请登录https://cloud.google.com/functions/docs/writing/http#handling_cors_requests。从该文档-

exports.corsEnabledFunction = (req, res) => {
  // Set CORS headers
  // e.g. allow GETs from any origin with the Content-Type header
  // and cache preflight response for an 3600s
  res.set("Access-Control-Allow-Origin", "*");
  res.set("Access-Control-Allow-Methods", "GET");
  res.set("Access-Control-Allow-Headers", "Content-Type");
  res.set("Access-Control-Max-Age", "3600");
  // Send response to OPTIONS requests and terminate the function execution
  if (req.method == 'OPTIONS') {
    res.status(204).send('');
  }
  // Continue with function code
  ...
}
wkyowqbh

wkyowqbh4#

我还花了一整天的时间来查找Firebase功能的CORS相关问题。
最后,我找到了解决办法。
默认情况下,firebase-functions是不可用在互联网上访问,我们必须为它创建一个原则并分配给该函数。
1.转到GCP控制台 Jmeter 板:
https://console.cloud.google.com/home/dashboard
1.在顶部搜索输入中搜索“Cloud Functions”,转到“Cloud Functions”。
1.然后,选择您的云功能(复选框)。
1.选择您的功能后,单击顶部的权限。
1.单击“添加主体”。
1.键入“allUsers”作为主体名称,并选择角色“Cloud Function Invoker”。* 您将看到一条消息,“Ability to invoke HTTP functions with restricted access.*
1.“保存”
就是这样!
现在每个人都可以从互联网上访问正确的配置到您的Firebase功能,而不会出现CORS错误。

见下图:

相关问题