Search code examples
ruby-on-railsamazon-s3cookiesamazon-cloudfrontstimulusjs

The Cookie header is not sent with the Fetch GET request to Cloudfront. Why?


I am trying to send a Fetch GET request from my Stimulus controller to Cloudfront along with some signed cookies for authenticating my request and retrieving the secured content.

Problem is that the cookies are not sent along despite the theoretically correct settings on both S3, Cloudfront, the Rails server and the client.

Environment

  • Cloudfront URL: https://netflix.tonyfromtokyo.online/mm57enm1nx2u91ztntbu2idxxror/HLS/mm57enm1nx2u91ztntbu2idxxror.m3u8

  • Client URL: http://tonyfromtokyo.online:3000/movies/298486374. I added to my /etc/hosts file the following line: 127.0.0.1 tonyfromtokyo.online so that I can send request from this domain instead of localhost:3000.

  • There is no CORS error happening on the browser. I allowed requests from http://tonyfromtokyo.online:3000.

cors settings

  • I set my Cloudfront response headers to be like this.

cloudfront response headers

  • Rails is setting the cookies like so:
cookies[key] = {
  value: value,
  domain: :all
}

They are correctly set as expected.

cookies

  • Now, the client code looks like this in my Stimulus controller.
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="video-player"
export default class extends Controller {
  static targets = [ "video" ]
  static values = { videoUrl: String }

  connect() {
    fetch(this.videoUrlValue, { credentials: 'include' }) // No cookies sent. Why?

    // https://spekiyoblog.com/how-to-set-cookie-to-hlsjs-request/
    const config =
      {
          xhrSetup: function (xhr, url)
          {
            xhr.withCredentials = true; // No cookies sent. Why?

          },
          fetchSetup: function (context, initParams)
          {
            console.log("fetchSetup");
              // Always send cookies, even for cross-origin calls.
              initParams.credentials = 'include';
              return new Request(context.url, initParams);
          },
      };

    if (Hls.isSupported()) {
      console.log("HLS supported");
      var hls = new Hls(config);

      hls.loadSource(this.videoUrlValue);
      hls.attachMedia(this.videoTarget);
      this.videoTarget.play();
    } else if (this.videoTarget.canPlayType('application/vnd.apple.mpegurl')) {
      this.videoTarget.src = this.videoUrlValue;
      this.videoTarget.addEventListener('canplay',function() {
        this.videoTarget.play();
      });
    }
  }
}

error response [request details5

  • The weird thing is that when I try to access the Cloudfront URL. It it passing correctly the cookies (proving that the cookies are correctly set in the browser).

success on direct access

If someone has an idea on how to fix this, I would really appreciate it. Thanks.

EDIT: the requests work fine on Mozilla and Safari (the cookies are sent with the request and I am able to retrieve the file via signed cookies). It still doesn't work in Chrome and Brave but it is a step forward.

  • Mozilla ✅
  • Safari ✅
  • Chrome ❌
  • Brave ❌

Solution

  • I found the solution. My Rails server was not using SSL (http) and it seems the cookies were not sent as part of the request to Cloudfront because of it. I didn't thought that was a problem at first.

    Once I setup SSL on my local Rails server, the cookies were sent as expected.

    request details

    The below article was quite helpful in guiding me setup SSL locally: https://jfbcodes.medium.com/using-rails-with-ssl-on-localhost-52d60f14a382