# Secured content with signed URLs

### Introduction

Zapp apps provides you the ability to used signed URL prior to playback.
Using signed URLs help you protect your content and prevent unauthorized viewers from viewing or downloading your content. A signed URL includes additional information, for example, an expiration date and time, that gives you more control over access to your content (e.g. `https://example.com/videos/example-hls.m3u8?token=some_token`).

Zapp provides a _Video Player Preload Plugin_, which can perform request to your signing service prior to playing your content. The protocol follows `pipesv2` endpoints protocol and allows you to leverage [context keys](./pipes2-endpoint-implementation-guide#using-context-parameters).

Setting Zapp _Video Player Preload Plugin_ as a hook to [Applicaster Video Player](/using-zapp/player/video-preload-hook) or any other video player will allow you to apply signed url flow on every attempt of users to play video in the app.

### Prerequisites

In order to use signed URLs, you are expected to have a signing server which could handle HTTP calls and is expected to respond in a [JSON:API](https://jsonapi.org/) format.

### Pipes2 Signer Endpoint Example

The following is a _Pipes2 Signing service Endpoint_ example implemented with [expressjs](https://expressjs.com/) that returns the expected JSON:API response (shown below):

```javascript
const express = require("express");
const app = express();
const port = 8080;
const base64url = require("base64url");

var Akamai = require("akamai-auth-token").default;

var config = {
  algorithm: "SHA256",
  acl: "/*",
  window: 6000,
  key: "myPrivateKey",
  encoding: false,
};

var akamai = new Akamai.default(config);

app.get("/signing_service", (req, res) => {
  var token = akamai.generateToken();

  // when using default signer url, the `src_url` is sent as part of the CTX object
  var context = JSON.parse(base64url.decode(req.query.ctx));

  res.set("Content-Type", "application/vnd.api+json");

  res.send({
    data: {
      type: "video",
      id: data.id,
      attributes: {
        stream_src: `${context["src_url"]}?token=${token}`,
      },
    },
  });
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});
```

The response should follow [Signed URL JSON schema](video-player-signed-url-json-schema).

### Using Context Parameters

_Video Player Preload Plugin_ can send additional parameters to the _Signer Endpoint_ when instructed to do so.
You can read more [here](https://docs.applicaster.com/integrations/pipes2-endpoint-implementation-guide#using-context-parameters).
This could be useful in case you would like to get some device or user information in order to sign the stream or return errors for un-permitted users.

### Signer Endpoint URL

The _Signer Endpoint_ could be defined in a similar way to [_Pipes2 Feed Endpoint_](https://docs.applicaster.com/using-zapp/managing-endpoints).

The default _Signed URLs service_ could be set in _Video Player Preload Plugin_ configuration. When using this option, the original stream src url will be added to the `ctx` object sent as part of the request.
