【问题标题】:How to set up CORS in Netlify Serverless function如何在 Netlify Serverless 功能中设置 CORS
【发布时间】:2019-09-10 03:54:55
【问题描述】:

我找不到如何使用无服务器 netlify 函数设置 CORS 的方法。 我已经使用这个函数示例来创建我自己的电子邮件表单发件人:

const nodemailer = require('nodemailer');

exports.handler = function(event, context, callback) {
    let transporter = nodemailer.createTransport({
        host: 'smtp.gmail.com',
        port: 465,
        secure: true,
        auth: {
            type: 'OAuth2',
            user: process.env.MAIL_LOGIN,
            clientId: process.env.CLIENT_ID,
            clientSecret: process.env.CLIENT_SECRET,
            refreshToken: process.env.REFRESH_TOKEN,
            accessToken: process.env.ACCESS_TOKEN
        }
    });
    console.log(event.body);

    transporter.sendMail({
        from: process.env.MAIL_LOGIN,
        to: process.env.MAIL_TO,
        subject: process.env.SUBJECT + new Date().toLocaleString(),
        text: event.body
    }, function(error, info) {
        if (error) {
            callback(error);
        } else {
            callback(null, {
                statusCode: 200,
                body: "Ok"
            });
        }
    });
}

但不幸的是,我可以通过每个域发送它,这并不安全,因为有些人可以将垃圾邮件发送到该收件箱。

你能跟我举个例子吗? 提前谢谢你

【问题讨论】:

  • 您好!我没有使用 netlify 的经验,但你不能只在请求属性上获取请求域(引用者)并在它不是你想要允许的域时设置停止脚本的条件吗?
  • 你检查了吗? github.com/netlify/…
  • 谢谢你们的回答。 @GuilhermeAssemany 我一直在考虑,但是如果有人会在 POSTMAN 中伪造它呢?
  • @BarakatTurki 听起来不错,问题是我必须在另一个页面中托管我的 React 应用程序,作为一个小部件,所以我不能在 Netlify 域上托管我的应用程序
  • 可能受托管域的服务器的 IP 限制?

标签: javascript node.js serverless netlify


【解决方案1】:

你可以这样做:

const headers = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'Content-Type',
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE'
};

if (event.httpMethod !== 'POST') {
    // To enable CORS
    return {
      statusCode: 200, // <-- Important!
      headers,
      body: 'This was not a POST request!'
    };
 }

这是我在更大的映射器函数中使用它的方式:

// src/customers.js
exports.handler = async (event, context) => {
  const path = event.path.replace(/\.netlify\/functions\/[^\/]+/, '');
  const segments = path.split('/').filter(e => e);

  switch (event.httpMethod) {
    case 'GET':
      // e.g. GET /.netlify/functions/customers
      if (segments.length === 0) {
        return require('./customers/read-all').handler(event, context);
      }
      // e.g. GET /.netlify/functions/customers/123456
      if (segments.length === 1) {
        event.id = segments[0];
        return require('./customers/read').handler(event, context);
      } else {
        return {
          statusCode: 500,
          body:
            'too many segments in GET request, must be either /.netlify/functions/customers or /.netlify/functions/customers/123456'
        };
      }
    case 'POST':
      // e.g. POST /.netlify/functions/customers with a body of key value pair objects, NOT strings
      return require('./customers/create').handler(event, context);
    case 'PUT':
      // e.g. PUT /.netlify/functions/customers/123456 with a body of key value pair objects, NOT strings
      if (segments.length === 1) {
        event.id = segments[0];
        console.log(event.id);
        return require('./customers/update').handler(event, context);
      } else {
        return {
          statusCode: 500,
          body:
            'invalid segments in POST request, must be /.netlify/functions/customers/123456'
        };
      }
    case 'DELETE':
      // e.g. DELETE /.netlify/functions/customers/123456
      if (segments.length === 1) {
        event.id = segments[0];
        return require('./customers/delete').handler(event, context);
      } else {
        return {
          statusCode: 500,
          body:
            'invalid segments in DELETE request, must be /.netlify/functions/customers/123456'
        };
      }
    case 'OPTIONS':
      // To enable CORS
      const headers = {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Headers': 'Content-Type',
        'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE'
      };
      return {
        statusCode: 200, // <-- Must be 200 otherwise pre-flight call fails
        headers,
        body: 'This was a preflight call!'
      };
  }
  return {
    statusCode: 500,
    body: 'unrecognized HTTP Method, must be one of GET/POST/PUT/DELETE/OPTIONS'
  };
};

我写了一篇关于如何在我启用了 CORS 的情况下构建无服务器数据库和 netlify 功能的教程,您可以找到文章 here

【讨论】:

  • 非常有趣,非帖子的错误响应需要保持 200。这绝对是我的问题。
【解决方案2】:
    exports.handler = async (event, context) => {
    return {
      statusCode: 200,
      headers: {
        /* Required for CORS support to work */
        'Access-Control-Allow-Origin': '*',
        /* Required for cookies, authorization headers with HTTPS */
        'Access-Control-Allow-Credentials': true
      },
      body: JSON.stringify({
        message: 'Hello from netlify',
        event: event,
      })
    }
  }

【讨论】:

    【解决方案3】:

    您也可以将 express 与 cors 一起使用。这是一种更好的动态处理 cors 选项的方式。

    我从我的项目中提取了自己的 netlify 配置并将其推送到 GitHub:

    https://github.com/kevludwig/netlify-functions-express

    还有一个使用nodemailer发送邮件的例子。

    【讨论】:

      猜你喜欢
      • 2020-05-27
      • 2020-10-11
      • 2021-08-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2018-11-06
      • 2019-12-16
      • 2020-02-21
      相关资源
      最近更新 更多