

# Générer et signer des jetons de lecture IVS
<a name="private-channels-generate-tokens"></a>

Pour plus d’informations sur l’utilisation des JWT et des bibliothèques prises en charge pour la signature de jetons, consultez la page [jwt.io](https://jwt.io/). Sur l'interface jwt.io, vous devez saisir votre clé privée pour signer les jetons. La clé publique n'est nécessaire que si vous souhaitez vérifier les jetons.

## Schéma de jeton
<a name="private-channels-tokens-schema"></a>

Tous les JWT présentent trois champs : header (en-tête), payload (charge utile) et signature.
+ **header** spécifie :
  + `alg` est l'algorithme de signature. Il s’agit d’ES384, un algorithme de signature ECDSA qui utilise l’algorithme de hachage SHA-384.
  + `typ` est le type de jeton, JWT.

  ```
  {
    "alg": "ES384",
    "typ": "JWT"
  }
  ```
+ **payload** contient des données spécifiques à Amazon IVS :
  + `channel-arn` est une référence pour la requête de lecture vidéo.
  + `access-control-allow-origin` est un champ facultatif qui peut être utilisé pour restreindre la lecture à des domaines [spécifiés](https://developer.mozilla.org/en-US/docs/Glossary/Origin), c'est-à-dire pour rendre une diffusion visible uniquement à partir d'un site Web spécifié. Par exemple, vous pouvez empêcher les utilisateurs d’intégrer le lecteur sur d’autres sites Web. Par défaut, la lecture est autorisée sur tous les domaines. (Notez que cela restreint uniquement le client navigateur ; cela ne restreint pas la lecture à partir d'un client non navigateur.) Ce champ peut contenir plusieurs origines séparées par des virgules. Les domaines génériques sont autorisés : chaque origine peut commencer son nom d’hôte par \* (exemple : https://\*.amazon.com). Si `strict-origin-enforcement` est `true`, vous pouvez spécifier au maximum cinq domaines ; sinon, il n’y a pas de maximum.
  + `strict-origin-enforcement` est un champ facultatif qui peut être utilisé pour renforcer la restriction d'origine spécifiée dans le champ `access-control-allow-origin`. Par défaut, la restriction `access-control-allow-origin` s'applique uniquement à la liste de lecture multivariante. Si l'option `strict-origin-enforcement` est activée, le serveur exigera que l'origine de la demande corresponde au jeton pour toutes les demandes de lecture (y compris les listes de lecture multivariantes, les listes de lecture variantes et les segments). Cela signifie que tous les clients (y compris les clients qui ne sont pas des navigateurs) devront fournir un en-tête de demande d'origine valide avec chaque demande. Utilisez la méthode `setOrigin` pour définir l'en-tête dans les kits SDK des lecteurs IVS iOS et Android. Il est défini automatiquement dans les navigateurs Web, à l'exception d'iOS Safari. Pour iOS Safari, vous devez ajouter `crossorigin="anonymous"` à l'élément vidéo pour vous assurer que l'en-tête de la demande d'origine est envoyé. Exemple : : `<video crossorigin="anonymous"></video>`. 
  + `single-use-uuid` est un champ facultatif qui contient un [identifiant unique universel (UUID)](https://en.wikipedia.org/wiki/Universally_unique_identifier) valide que vous générez dans le cadre de la création du jeton. Si vous ajoutez ce champ et une valeur UUID, le jeton associé que vous générez est invalidé une fois qu'il est utilisé pour récupérer une liste de lecture multivariante et regarder un flux. Les jetons d'authentification à usage unique empêchent les utilisateurs malveillants de partager un flux sur vos chaînes privées avec d'autres spectateurs. Notez que lors de l’utilisation de la réclamation `single-use-uuid`, la valeur maximale de la réclamation `exp` est de 10 minutes dans le futur.
  + `viewer-id` est un champ facultatif qui contient un identifiant utilisé pour le suivi et pour faire référence à l'utilisateur auquel le jeton est accordé. Ce champ est obligatoire pour pouvoir révoquer la session de visionnage de l'utilisateur à l'avenir. La longueur maximale est de 40 caractères et la valeur doit être considérée comme une chaîne. N'utilisez pas ce champ pour des informations d'identification personnelle, confidentielles ou sensibles. Notez que lors de l'utilisation de `viewer-id`, la valeur maximale de `exp` est de 10 minutes dans le futur.
  + `viewer-session-version` est un champ facultatif qui contient une version à associer à cette session de visionnage. Lorsque vous révoquez des sessions d'utilisateur, cette valeur peut être utilisée pour filtrer les sessions de visionnage qui sont révoquées. Par exemple, la spécification d'un horodatage Unix ici permettrait de révoquer toutes les sessions démarrées avant l'heure spécifiée. La valeur doit être un entier signé sur 64 bits (Int64). Ce champ est censé être fourni (facultatif) avec `viewer-id` ; seul, il ne sert à rien. La valeur par défaut est 0.
  + `maximum-resolution` vous permet de spécifier le filtrage des manifestes par résolution pour une session d'utilisateur, en fonction des droits de l'utilisateur. Par exemple, si ce champ est défini sur `HD`, l'utilisateur recevra une résolution inférieure ou égale à `HD`.
  + `ads-opt-out` est un champ facultatif qui vous permet d’exclure un spectateur de la réception des annonces. Les valeurs autorisées sont `true` et `fals`e. La valeur par défaut lorsque ce champ est exclu est `false`. Pour plus d’informations, consultez [Insertion d’annonces côté serveur](https://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/server-side-ad-insertion.html).
  + `ads-player-params` est un champ facultatif qui vous permet de transmettre des paramètres à Elemental MediaTailor comme s’il s’agissait de paramètres du lecteur. Les clés que vous insérez dans cette liste sont toujours placées dans l’espace de noms des paramètres de modèle `player_params`. La taille totale des données utiles pour l’ensemble des clés et valeurs combinées est limitée à 1 000 octets.
  + `exp` est un horodatage Unix UTC du moment où le jeton expire. Cela n’indique pas la durée pendant laquelle le flux peut être visualisé. Le jeton est validé lorsque l'utilisateur lance la lecture, pas tout au long du flux. Saisissez cette valeur en tant que valeur du type d’entier.

    Notez qu'un horodatage Unix est une valeur numérique représentant le nombre de secondes entre le 1970-01-01T00:00:00Z UTC et la date/heure UTC spécifiée, sans tenir compte des secondes intercalaires. Différents langages mesurent les horodatages Unix dans différentes unités ; par exemple, la fonction `Date.now()` de JavaScript renvoie le temps en millisecondes. (Consultez `exp` dans la [section 4.1.4 de la RFC du JWT](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4).)

  ```
  {
      "aws:channel-arn": "<channel_arn>",
      "aws:access-control-allow-origin": "<your-origin>",
      "aws:strict-origin-enforcement": true,
      "aws:single-use-uuid": "<UUID>",
      "aws:viewer-id": "<viewer_id>",
      "aws:viewer-session-version": "<viewer_session_version>",
      "aws:maximum-resolution": "SD" | "HD" | "FULL_HD",
      "exp": <unix timestamp>
  }
  ```
+ Pour créer la **signature**, utilisez la clé privée avec l’algorithme spécifié dans l’en-tête (ES384) pour signer l’en-tête encodé et la charge utile encodée.

  ```
  ECDSASHA384(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    <private-key>
  )
  ```

## Instructions
<a name="private-channels-tokens-instructions"></a>

1. Générez la signature du jeton à l'aide de l'algorithme de signature ES384 et une clé privée associée à l'une de vos ressources de clé de lecture (consultez l'exemple `ECDSASHA384` ci-dessus).

1. Assemblez le jeton.

   ```
   base64UrlEncode(header) + "." +
   base64UrlEncode(payload) + "." +
   base64UrlEncode(signature)
   ```

1. Ajoutez le jeton signé à l’URL de lecture en tant que paramètre de requête.

   ```
   https://b37c565f6d790a14a0e78afaa6808a80.us-west-2.playback.live-video.net/
   api/video/v1/aws.ivs.us-west-2.123456789.
   channel.fbc789c1-2c56-4ce6-a30a-d99275dc4481.m3u8?token=<token>
   ```

## Exemple de module Node.js
<a name="private-channels-tokens-nodejs-example"></a>

Vous trouverez ci-dessous une façon de générer un jeton sur le dorsal (via un microservice ou une application sans serveur) à l’aide de Node.js. 

```
import jwt from "jsonwebtoken";

const getToken = () => {
  const privateChannelArn = process.env.DEMO_PRIVATE_CHANNEL_ARN; // private channel ARN
  const privateChannelPrivateKey = process.env.DEMO_PRIVATE_CHANNEL_PRIVATE_KEY; // playback private key

  const payload = {
    "aws:channel-arn": privateChannelArn,
    "aws:access-control-allow-origin": "*",
    "exp": Date.now() + (60 * 1000), // expires in 1 minute
  };

  const token = jwt.sign(payload, privateChannelPrivateKey, { algorithm: 'ES384' });
  return token;
}
```

Dans votre application frontale, vous pouvez récupérer ce jeton et l’ajouter à l’URL de lecture du canal privé, comme indiqué ci-dessous. 

```
const streamUrl = `https://b37c565f6d790a14a0e78afaa6808a80.us-west-2.playback.live-video.net/api/video/v1/aws.ivs.us-west-2.123456789.channel.fbc789c1-2c56-4ce6-a30a-d99275dc4481.m3u8?token.m3u8?token=${token}`
const ivsPlayer = IVSPlayer.create();
ivsPlayer.attachHTMLVideoElement(document.getElementById('video-player'));
ivsPlayer.load(streamUrl);
ivsPlayer.play();
```