@spencerbeggs/aws-lambda-cors
v2.0.3
Published
Utility module for basic handling of CORS responses for serverless AWS Lambda functions attached to API Gateway.
Downloads
2
Maintainers
Readme
AWS Lambda CORS
AWS has made setting up microservice APIs a breeze by attaching Lambda functions to API Gateways with via Lambda Proxy Integrations in API Gateway. But when you need more than basic CORS handling you may find yourself writing a lot of duplicate or too-clever-by-half code to handle setting proper headers on your responses. Testing your handlers directly with a testing library like Jest can also become a chore as you may find yourself working around your CORS-handling code. This module attempts to abstrct basic header handling handling to allow you to focus of the business-logic of your serverless functions.
Basic Usage
const { cors } = require("@spencerbeggs/aws-lambda-cors");
module.export.handler = function() {
const { event, context, callback, data, response } = cors(...arguments);
response.body = JSON.stringify({
message: "Hello, world!"
});
callback(null, response);
};
The cors
function will automatically respond with a 204 repsonse when it encounters a OPTIONS
request with the Access-Control-Allow-Origin
, Access-Control-Allow-Headers
, Access-Control-Allow-Methods
andAccess-Control-Max-Age
. For other types of requests the function returns the regular event
, context
and callback
arguments available to a Lamabda functions you would expect to from a proxy integration.
The response
argument is simply an object with origin headers setup and its statusCode
propery set to 200
. If you want to send a JSON response, you need to set the body property of the response
object and send stringified JSON.
If the event passed to your function has a Content-Type
header starting with to application/json
, the function attempts to parse the event body with JSON.parse
and return the resulting JSON as the data
return value. If the body cannot be parsed into JSON, the funtion will automatically callback with a 400 response.
Note: You can set module.exports.handler
to function()
or async function()
but you cannot set it to () =>
or async () =>
because fat arrow functions do not have bindings to the arguments keyword.
Advanced Usage
The cors
function takes a second options
argument that is an object, with the following optional properties: allowedOrigins
, allowedMethods
, allowedHeaders
and maxAge
. The allowedOrigins
, allowedMethods
and allowedHeaders
properties can be passed as either arrays of strings or as a comma-seperated string. maxAge
is just a string. You can also pass these options from process.env
with the respective vaiable names: CORS_ALLOWED_ORIGINS
, CORS_ALLOWED_METHODS
, CORS_ALLOWED_HEADERS
and CORS_MAX_AGE
.
const { cors } = require("@spencerbeggs/aws-lambda-cors");
module.export.handler = function() {
const options = {
allowedOrigins: ["https://mysite.com", "https://anothersite.com"]
allowedMethods: ["POST", "PATCH"],
allowedHeaders: "X-Custom-Header",
maxAge: "800"
};
const { event, context, callback, data, response } = cors(...arguments, options);
response.body = JSON.stringify({
message: "Hello, world!"
});
callback(null, response);
};
The default options object looks like:
const options = {
allowedOrigins: "*",
allowedMethods: ["GET", "OPTIONS", "POST", "PUT", "PATCH", "DELETE"],
allowedHeaders: [
"Content-Type",
"X-Amz-Date",
"Authorization",
"X-Api-Key",
"X-Amz-Security-Token"
],
maxAge: "600"
};
You can also set the options by passing values to process.env
: process.env.CORS_ALLOWED_ORIGINS
, process.env.CORS_ALLOWED_METHODS
, process.env.CORS_ALLOWED_HEADERS
and process.env.CORS_MAX_AGE
.
Example CloudFormation Template
Below is a simple CloudFormation template that uses AWS:Serverless Transform that attaches API Gateway to a serverless function handler for your API endpoint. Note that both the POST
and OPTIONS
events point to the same code bundle as this module provides the CORS handling for both.
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Resources:
Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- "lambda.amazonaws.com"
Action:
- "sts:AssumeRole"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
- "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
MyFunction:
Type: "AWS::Serverless::Function"
Properties:
CodeUri: s3://my-lambda-functions-bucket/myfunction.zip
Handler: index.handler
Runtime: nodejs10.x
Role: !GetAtt Role.Arn
Timeout: 3
Environment:
Variables:
CORS_ALLOWED_ORIGINS: "https://siteone.com,https://sitetwo.com"
CORS_ALLOWED_METHODS: "POST"
Events:
post:
Type: Api
Properties:
Path: /my-endpoint
Method: POST
options:
Type: Api
Properties:
Path: /my-endpoint
Method: OPTIONS