Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set up CORS in Netlify Serverless function

I couldn't find any way how can I set up CORS using serverless netlify functions. I have used this function example to create my own e-mail form sender:

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"
            });
        }
    });
}

But unfortunately, I am able to send it through every single domain which is not really safe as some people can send spam into that inbox.

Would you be able to follow me to any example? Thank you in advance

like image 292
user4572896 Avatar asked Apr 20 '19 00:04

user4572896


People also ask

How do I create a serverless function in Netlify?

Creating Your First Serverless FunctionInside of the new netlify/functions directory, create a new file hello-world. js . Use the export syntax and create an async function called handler , that returns a statusCode of 200 and a body with the message that is stringified with the JSON. stringify method.

How do you test Netlify functions?

To test Netlify on a local server, you need to run Netlify dev as a part of your project directory. Make sure that your functions can access the project environment variables. Then it should be able to serve on a port that's similar to your web project.

Does Netlify use AWS Lambda?

You can now deploy serverless AWS Lambda functions on Netlify without configuring API gateways, coordinating deployments, or setting up an AWS account. Just add each serverless function as a file in your Git repository and Netlify will take care of the rest.


2 Answers

    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,
      })
    }
  }
like image 61
Viraj Singh Avatar answered Oct 12 '22 22:10

Viraj Singh


You can do something like this:

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!'
    };
 }

Here is how I used it in a larger mapper function:

// 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'
  };
};

I wrote a tutorial about how to work build serverless databases & netlify functions where I had CORS enabled, you can find the article here.

like image 36
ahmaman Avatar answered Oct 12 '22 22:10

ahmaman