Columbus, Ohio

AWS 2024 DC Summit DEV206 Create DEV, QA, and UAT environments using unique domain names

Welcome 2024 AWS Summit Washington, DC attendee!

Please leave a review for my session within the AWS Events application as soon as you get a moment.

Links

  • Follow me on LinkedIn
  • Session Slides: Download
  • Session Video: COMING SOON (I will be making a video and posting on Youtube this July)
  • See my code on GitHub (coming soon)
  • Example CloudFormation (coming soon)
  • How to use SES in Sandbox mode for lower environments (coming soon)

CloudFront Function – Open Sesame

The following CloudFront function shows an example how you can use a cookie and a query string parameter to allow access to a CloudFront distribution with exception paths as a regular expression to allow certain paths to pass thru. Please change the secretWord, cookieValue and exceptionRegex value to meet your needs.

/*
* Deny access to CloudFront distro unless a magic cookie is set or path in exception regex
* By Angelo Mandato (https://angelo.mandato.com)
*/

const secretWord = 'sesame'; // Secret word
const cookieValue = '465d06d6-2e9e-4b5c-b716-e2b6d199fd02'; // Random value that if set, allows entry
const exceptionRegex = /^\/(api|webhook)/; // Exception regular expression

function handler(event) {
    const req = event.request;

    if( exceptionRegex && req.uri.match(exceptionRegex) ) {
        return req; // Exception list, let them through!
    }

    // Delete the cookie ?close=secretWord
    if( req.querystring["close"] && req.querystring["close"].value == secretWord ) {
        // Let them pass, set the cookie
        const resp = {
            statusCode: 200,
            statusDescription: 'Ok',
            cookies: {
                "magic_cookie": {
                    "value" : "",
                    "attributes": "Secure; HttpOnly; Expires=Thu, 01 Jan 1970 00:00:00 GMT"
                }
            },
            body: {
                "encoding": "text",
                "data": "<!DOCTYPE html><html><head><title>Good bye!</title></head><body>"+
                "<p>Thanks for all the fish!</p></body></html>"
            }
        }
        return resp;
    }

    // Create the cookie ?open=secretWord
    if( req.querystring["open"] && req.querystring["open"].value == secretWord ) {
        var e = new Date();
        e.setDate(e.getDate() + 1); // 1 day cookie

        // Let them pass, set the cookie
        const resp = {
            statusCode: 200,
            statusDescription: 'Ok',
            cookies: {
                "magic_cookie": {
                    "value" : cookieValue,
                    "attributes": "Secure; HttpOnly; Expires=" + e.toUTCString()
                }
            },
            body: {
                "encoding": "text",
                "data": "<!DOCTYPE html><html><head><title>Welcome!</title></head><body>"+
                "<p>Welcome to the party! <a href=\""+ req.uri +"\">Continue</a></p></body></html>"
            }
        }
        return resp;
    }

    // If no cookie or the cookie is not the value we are looking for
    if( !req.cookies["magic_cookie"] || req.cookies["magic_cookie"].value != cookieValue ) {
        // Access denied!
        const resp = {
            statusCode: 503,
            statusDescription: 'Service Unavailable',
            body: {
                encoding: "text",
                data: "<!DOCTYPE html><html><head><title>Sorry!</title>"+
                    "<meta name=\"robots\" content=\"noindex, nofollow\" />"+
                    "</head><body><p>No soup for you!</p></body></html>"
            }
        };
        return resp;    
    }
    
    return req; // Let them have cake!!!
}
// eof

Join My FREE Newsletter

Get the latest news and episodes of the Cloud Entrepreneur Podcast and Angelo’s development blog directly in your inbox!