CloudFront Cookie-Based Redirection using CloudFront functions

Atit Shah
5 min readFeb 12, 2024
Photo by Arisa Chattasa on Unsplash

One very common usage for cookies is the fact that they are normally used to identify valid users for our applications and if such users have specific sessions opened on the server. This can also be extended to allow the identification of any particular cookies from the request and redirect the viewers based on it. In this scenario, the idea is to redirect requests based on whether the requests coming have set cookies or not.

Pre-Requiste: You should have a CloudFront Distribution created with an S3 bucket as an origin.

In this redirect scenario, the idea is going to be to identify if the request coming in has previously set cookies which our backend application can use to identify that particular user, and if that is not the case you will then redirect the request to a sign-in page.

This is a simple scenario which will help illustrate how to implement such redirects, however, it can be expanded to handle much more complex scenarios where multiple cookie values can be evaluated or even a combination of cookies and header values to allow a comprehensive decision around if the user should be redirected to a login page or not.

Step 1: Create a CloudFront Function which will evaluate cookie values

Our first action is going to be to create the function that will be executed and evaluate the cookie values.

  1. Open the CloudFront Console
  2. Go to “Functions” and then click on “Create function”
  3. In the “Create function” page, provide “edge-cookie-redirect” as the function name and click “Create function”. You should now be at the Function page, where you can add, edit and publish your function code.
  4. Under the “Build” and “Development” tabs, add the following code block:
function handler(event)  {  
console.log('code is starting')
var request = event.request;
var cookie_exists = request.cookies
//evaluates if a request has a cookie, if it does not immediately redirects the viewer to the login page
if (cookie_exists.session == null) {
console.log("start if block")
var response = {
statusCode: 301,
statusDescription: 'Permanent Redirect',
headers:
{"location": { "value": "/login.html" } }
}
return response;

//in case the first condition is false, it means we have a cookie, we need to know now if the cookie we need is set to the value we need.
} else if (cookie_exists.session.value != "true") {
console.log("start else if block")
var response = {
statusCode: 301,
statusDescription: 'Permanent Redirect',
headers:
{ "location": { "value": "/login.html" } }
}
return response;

// if none of the above conditions are met it means the cookie is set, then we just allow the request to proceed as is
} else {
return request;
}
}

The following image shows what you should have under your “Development” tab after pasting the code block. Then click “Save changes”.

5. Once the changes to the code have been saved, click on the “Publish” tab, and then “Publish function”. This will make the code that’s in the development stage to go to the live stage.

Step 2: Associate the function with the CloudFront Cache Behavior.

To accomplish our redirect use case, we will be associating this function with the default behaviour, it essentially means that any user going to our main page will be redirected to the login page if they do not have the proper cookies.

  1. In the Publish tab of our function, we will click on “Add association”.
  2. In the new window, choose your CloudFront distribution, under “Event type” we will choose “Viewer request”, and under “Cache behaviour”, we will choose “Default”, then hit “Add association”.

Step 3: Adding a login cache behaviour

  1. Go to the CloudFront Console
  2. Open your distribution, go to the “Behaviors” tab, then click on “Create behaviour”.
  3. Under “Path Pattern”, enter “login.html”, and under “Origin and origin groups” choose your S3 origin.
  4. Under “Viewer protocol policy”, select “Redirect HTTP to HTTPS”. Leave the rest of the settings as default and click “Save changes”.

Step 4: Testing the redirect

  1. Go to the CloudShell Console

Testing a request without any cookies, run this command

curl -v https:///d1234.cloudfront.net

As usual, replace the domain name with the domain from your distribution. You should see a result of the following:

< HTTP/1.1 301 Permanent Redirect < Server: CloudFront < Content-Length: 0 < Connection: keep-alive < Location: /login.html < X-Cache: FunctionGeneratedResponse from cloudfront < X-Amz-Cf-Pop: IAD89-C3 < X-Amz-Cf-Id:
  • First is the response itself, which is a redirect to our login.html page.
  • Second is the “X-Cache” header, which shows the response from our CloudFront function. You can try this on any browser and you should see us going to the login page as follows:

Testing a request with session cookie as false. Here you will be sending a request to our distribution, where you will simulate having a cookie set by the application, however, this cookie is not the required one, the logic understands this as a user that does not have a valid session. Run the below command

curl -v --cookie "session=false" https://d1234.cloudfront.net

The result should look like:

< HTTP/1.1 301 Permanent Redirect < Server: CloudFront < Content-Length: 0 < Connection: keep-alive < Location: /login.html < X-Cache: FunctionGeneratedResponse from cloudfront < X-Amz-Cf-Pop: IAD89-C3 < X-Amz-Cf-Id:

This response seems similar to the one you saw previously, which is expected as our session cookie being set to false also should redirect the user to our login page.

Testing a request with a valid cookie. Run the below command:

curl -v --cookie "session=true" https://d1234.cloudfront.net. 

The result should look like:

< HTTP/1.1 200 OK < Content-Type: text/html < Content-Length: 86 < Connection: keep-alive < ETag: "4cd5f4a0695fe044b77273039e521b09" < Accept-Ranges: bytes < Server: AmazonS3 < X-Cache: Miss from cloudfront < X-Amz-Cf-Pop: IAD89-C3 < X-Amz-Cf-Id:
<!DOCTYPE html> 
<html>
<body>
<h1>Main Page</h1>
<p>Main Page</p>
</body>
</html>

You can see here that this request was not redirected, but instead, it went to the main page and returned the content as expected to the user.

--

--