How to send cookies along with requests in the Player SDKs

Tutorial for configuring the player SDKs across platforms to accept cookies from Set-Cookie HTTP headers and send them along in following requests.

Overview

It is often required to accept cookies and send cookies along with requests, for different reasons. A common use case where this could be required is signed token URLs. When the first DASH or HLS manifest is requested, the server send a Set-Cookie HTTP response header, which the client should accept. On every subsequent request, like manifest updates or segment requests on the same domain, it should send the provided cookie back to the server to authenticate and get access to the requested files.

While this may work out of the box on some platforms, it does not on others. This tutorial will go through the required setup for the different Bitmovin Player SDKs.

Requirements

  1. Web SDK Version: 8.0.0 or higher
  2. Android SDK Version: 3.0.0 or higher
  3. iOS SDK Version: 3.0.0 or higher
  4. Roku SDK Version: 1.34.0 or higher
  5. Chromecast Receiver using CAF: Custom handling in the receiver, as demonstrated in https://github.com/bitmovin/bitmovin-player-caf-receiver

Web

On web browsers, it’s the default behavior to accept cookies from servers via the Set-Cookie HTTP header, and it is used on the following requests. There is no need for any configuration.

However, in order to allow cookies to be sent also in cross-site requests, you will need to explicitly allow this for security reasons as shown below. The withCredentials option is tightly coupled with JavaScript’s XMLHttpRequest.withCredentials, please refer to XMLHttpRequest.withCredentials on MDN for full details about this flag.

const source = {
  // your DASH/HLS stream URLs and other source properties go here

  options: {
    withCredentials: true
  }
}

In the player’s source object, you can specify an additional options object which can take an optional withCredentials property to enable cross-origin cookie handling.

Safari

Due to limitations from Apple, Safari requires a slightly more complex setup to get cookies to work properly. To enable the full functionality, it is required to set up a Service Worker. Please refer to our Github sample on how to set this up: https://github.com/bitmovin/bitmovin-player-web-samples/tree/main/serviceworker

Android, Android TV and Amazon FireTV

The expected cookie handling is not working per default on Android platforms. This requirement can be solved easily though by setting a default Cookie Manager at the application level. The following code should go in the main activity:

private static final CookieManager DEFAULT_COOKIE_MANAGER;
static {
  DEFAULT_COOKIE_MANAGER = new CookieManager();
  /** Here we can set a cookie policy. 
    * Either `ACCEPT_ALL` or `ACCEPT_ORIGINAL_SERVER`, both should do the trick in this case.
   **/
  DEFAULT_COOKIE_MANAGER.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
  if (CookieHandler.getDefault() != DEFAULT_COOKIE_MANAGER) {
    CookieHandler.setDefault(DEFAULT_COOKIE_MANAGER);
  }
}

It first creates a new instance of the CookieManager, which is a default Android class (API level 9+). We set a CookiePolicy on that instance using the setCookiePolicy method, in the example above we use the value ACCEPT_ORIGINAL_SERVER (see https://developer.android.com/reference/java/net/CookiePolicy for details and other options). Finally, we’re setting our instance as the CookieHandler's default (setDefault method). This should be done at the beginning of an HTTP session.

With this, you are all set. However, Android offers more customizations if needed, see https://developer.android.com/reference/java/net/CookieManager for more details and options.

iOS and tvOS

On iOS and tvOS, AVFoundation already handles most of the cookies. To leverage that, you will have to change a particular player configuration setting:

let playerConfig = PlayerConfig()
let tweaksConfig = TweaksConfig()
tweaksConfig.isCustomHlsLoadingEnabled = false
playerConfig.tweaksConfig = tweaksConfig

First, we create a PlayerConfig as usual (line 1). Then a TweaksConfig is created (line 3) and the isCustomHlsLoadingEnabled property of it is set to false (line 3). This is the important part as it disables the manifest loading done by the Bitmovin Player SDK and offloads this task to AVFoundation instead. Finally, the created TweaksConfig is added to the PlayerConfig (line 4). Once this is done, Set-Cookie HTTP headers are accepted and applied to the following request like manifest updates or segment downloads as expected.

This approach comes with downsides as some features and events are not supported in this mode. This includes, but is not limited to:

  • MetadataEvents carrying segment-specific metadata for custom HLS tags, like #EXT-X-SCTE35
  • MetadataParsedEvents carrying segment-specific metadata for custom HLS tags, like #EXT-X-SCTE35
  • DrmDataParsedEvents when a #EXT-X-KEY is found
  • Player.availableVideoQualities is missing some information
  • DownloadFinishedEvents for playlist downloads
  • SourceWarningEvents when no #EXT-X-PLAYLIST-TYPE is found

Roku

This is supported out of the box in the Bitmovin Player Roku SDK starting with version 1.34.0, without any further settings.

Chromecast (CAF)

CAF (Chromecast Application Framework) receiver apps do not use the Bitmovin Player as Google does not allow third-party players.

CAF allows to customise requests before they are issued. This enables you to set the withCredentials flag in the manifestRequestHandler, segmentRequestHandler or the captionRequestHandler according to your needs.

Bitmovin’s sample CAF receiver already includes such code and transfers the settings from the CAF sender player SDKs to the receiver.