Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use CloudFront signed cookies in the browser?

So I have a private CDN (can't access data through S3, only by signed URL & cookies) using CloudFront that holds some files for a web application.

One of the pages on my site displays an image whose source lives on the cdn.

<img src="cdn.example.com/images/file.jpg">

Now when I generate a signed URL on the server I can just pass it to the client and set it as source...Easy

But when I try to do the same thing using signed cookies I run into 2 problems:

  1. After generating the signed cookies server-side, I set them using res.cookie but I'm not sure how to find them in response on the client side.
  2. In the event of actually getting the cookie on the client side (in angular/javascript), how to I "set" it so that when the browser tries to grab the image in the above mentioned html it allows access?

I'm using node, express, and cookie-parser. I'm fairly new to this stuff so any help is appreciated

like image 225
crazyCoder Avatar asked Feb 01 '17 22:02

crazyCoder


People also ask

How do I enable cookies in CloudFront?

If you want to receive cookies at your origin but you don't want CloudFront to cache the Set-Cookie headers in your origin's responses, configure your origin to add a Cache-Control header with a no-cache directive that specifies Set-Cookie as a field name. For example: Cache-Control: no-cache="Set-Cookie" .

What is CloudFront cookies?

CloudFront signed cookies allow you to control who can access your content when you don't want to change your current URLs or when you want to provide access to multiple restricted files, for example, all of the files in the subscribers' area of a website.


2 Answers

Have you checked that the domain for the cookie is the same or a subdomain of the CloudFront CDN?

The cookie will be included in the request to the CloudFront distribution only if it is coming from a related domain. For example, if you are testing locally using "localhost" that won't work as the cookie domain is "localhost" but the signed cookie domain is "cdn.example.com".

To ensure that the domain is correct:

  1. Set up a CNAME for the CloudFront Distribution e.g. http://cdn.example.com

  2. Make sure the signed cookie has the correct domain e.g. domain:'*.example.com' will match against the domain.

There's a good article here: https://www.spacevatican.org/2015/5/1/using-cloudfront-signed-cookies/

There's also a good node module for creating signed cookies: https://github.com/jasonsims/aws-cloudfront-sign

Using this module you would do something like:

const options = {
    keypairId: YOUR_ACCESS_ID,
    privateKeyPath: PATH_TO_PEM_FILE
};

const signedCookies = cf.getSignedCookies("http://cdn.example.com/*", options);

for (const cookieId in signedCookies) {
    res.cookie(cookieId, signedCookies[cookieId], {domain: ".example.com"});
}

Note the way I set the domain. If not explicitly set it will default to the one that made the request, which is probably not what you want.

Last thing, to test this locally, I set up port-forwarding on my home network and created a CNAME in GoDaddy to point to my home IP e.g. "test.example.com". I then used "http://test.example.com" instead of "http://localhost". This created a cookie with the subdomain "test.example.com". Finally, I created another CNAME in GoDaddy called "cdn.example.com", pointing it to the CloudFront URL. I used the wildcard domain in my signed cookie, ".example.com" and because I now have the signed cookie on the same domain "example.com" it's passed to CloudFront and boom we have liftoff!

like image 115
Click Ahead Avatar answered Sep 28 '22 08:09

Click Ahead


For those trying to access a protected resource in CloudFront from a different domain you can not set the cookies cross domain so you're limited to using Signed URLs instead. However you can use javascript on the CloudFront site to use the parameters in the Signed URL to create a Signed Cookie directly in CloudFront. I put together a simple JS script that does just that.

aws-signed-cookie-from-signed-url.js

  • build signed url in www.mysite.com that points to CloudFront url www.cloudfronturl.com/sample/index.html
  • included the JS in the CloudFront resource "sample/index.html"
  • upon the user using the signed URL, index.html will create the SignedCookie which will allow all additional navigation within www.cloudfronturl.com/sample to work based on the cookie
like image 27
darbelaez Avatar answered Sep 28 '22 07:09

darbelaez