

# 產生和簽署 IVS 播放權杖
<a name="private-channels-generate-tokens"></a>

如需有關使用 JWT 以及用於簽章符記的支援程式庫的詳細資訊，請造訪 [jwt.io](https://jwt.io/)。在 jwt.io 介面上，您必須輸入私有金鑰才能簽署符記。只有在您想驗證符記時才需要公有金鑰。

## 符記結構描述
<a name="private-channels-tokens-schema"></a>

所有 JWT 都有三個欄位：標頭、承載和簽章。
+ **標頭**指定：
  + `alg` 是簽章演算法。這是 ES384，一種使用 SHA-384 雜湊演算法的 ECDSA 簽章演算法。
  + `typ` 是符記類型，JWT。

  ```
  {
    "alg": "ES384",
    "typ": "JWT"
  }
  ```
+ **承載**包含 Amazon IVS 特定資料：
  + `channel-arn` 是影片播放請求的參考。
  + `access-control-allow-origin` 是一個選用欄位，可用來限制指定[來源](https://developer.mozilla.org/en-US/docs/Glossary/Origin)的播放；也就是說，只能從指定的網站檢視串流。例如，您可能想要防止使用者在其他網站內嵌播放器。預設情況下，允許在所有來源播放。(請注意，這只會限制瀏覽器用戶端；它不會限制從非瀏覽器用戶端播放)。此欄位可能包含多個來源，用逗號分隔。允許使用萬用字元網域：每個來源的主持人名稱可以 \* 開頭 (例如：https://\*.amazon.com)。如果 `strict-origin-enforcement` 為 `true`，則最多可以指定 5 個網域；否則，沒有上限。
  + `strict-origin-enforcement` 是選用欄位，可用於強化 `access-control-allow-origin` 欄位中指定的原始限制。根據預設，`access-control-allow-origin` 限制僅會套用至多變體播放清單。如果已啟用 `strict-origin-enforcement`，伺服器會強制執行要求，使請求來源與所有播放請求 (包括多變體播放清單、變體播放清單和區段) 的字符相符。這表示所有用戶端 (包括非瀏覽器用戶端) 必須為每個請求提供有效的原始請求標頭。使用 `setOrigin` 方法來設定 IVS iOS 和 Android 播放器 SDK 中的標頭。系統會在 iOS Safari 以外的網頁瀏覽器中自動進行該設定。針對 iOS Safari，您需要將 `crossorigin="anonymous"` 新增至影片元素，以確認傳送原始請求標頭。範例：`<video crossorigin="anonymous"></video>`。
  + `single-use-uuid` 是選用欄位，其中含有您在編寫權杖時產生的有效[通用唯一識別符 (UUID)](https://en.wikipedia.org/wiki/Universally_unique_identifier)。如果您新增此欄位和 UUID 值，則您產生的相關聯權杖一旦用於擷取多版本播放清單並觀看串流後，便會失效。單次使用身分字符會使惡意使用者更難以向其他觀眾分享您私人頻道上的串流。請注意，使用 `single-use-uuid` 宣告時，日後 `exp` 宣告的最大值為 10 分鐘。
  + `viewer-id` 是選擇性欄位，其中包含授予瀏覽器符記時，於追蹤和參照瀏覽器的 ID。需要此欄位才能在之後撤銷檢視器的檢視工作階段。最大長度為 40 個字元，且值必須符合字串的資格。請勿將此欄位用於個人識別、機密或敏感資訊。請注意，使用 `viewer-id` 時，日後 `exp` 的最大值為 10 分鐘。
  + `viewer-session-version` 是選擇性欄位，其中包含與此檢視器工作階段相關聯的版本。撤銷檢視器工作階段時，此值可用來篩選要撤銷的檢視器工作階段。例如，在此處指定 Unix 時間戳記，將允許撤銷在指定時間之前啟動的所有工作階段。該值必須是 64 位元帶正負號的整數 (Int64)。此欄位的用意是與 `viewer-id` 一起提供 (選用)；此欄位單獨存在沒有任何作用。預設值為 0。
  + `maximum-resolution` 可讓您依據檢視器工作階段 (根據檢視器權利) 的解析度來指定資訊清單篩選功能。例如，將此欄位設定為 `HD`，表示檢視器會收到小於或等於 `HD` 的解析度。
  + `ads-opt-out` 是選用欄位，可讓您選擇不接收廣告的觀眾。允許的值為 `true` 和 `fals`。排除此欄位時的預設值為 `false`。如需詳細資訊，請參閱[伺服器端廣告插入](https://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/server-side-ad-insertion.html)。
  + `ads-player-params` 是選用欄位，可讓您將參數當作播放器參數傳遞給 Elemental MediaTailor。您在此清單中放置的索引鍵一律會當作 `player_params` 範本參數加入命名空間。所有索引鍵和值合併的總承載大小限制為 1000 個位元組。
  + `exp` 是符記過期時的 Unix UTC 時間戳記。這並不表示可以檢視串流的時間長度。當觀眾初始化播放時，會驗證符記，而不是整個串流。請輸入此數值做為整數類型值。

    請注意，Unix 時間戳記是一個數值，表示從 1970-01-01T00:00:00Z UTC 到指定 UTC 日期/時間的秒數 (忽略閏秒)。不同的語言會以不同的單位來衡量 Unix 時間戳記；例如 JavaScript 的 `Date.now()` 以毫秒為時間單位傳回。(請參閱 [JWT RFC 第 4.1.4 節](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4)中的 `exp`。）

  ```
  {
      "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>
  }
  ```
+ 若要建立**簽章**，請使用私有金鑰搭配標頭 (ES384) 中指定的演算法來簽署已編碼的標頭和承載。

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

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

1. 使用 ES384 簽章演算法，以及與其中一個播放金鑰資源相關聯的私有金鑰，來產生符記簽章 (請參閱前述 `ECDSASHA384` 範例)。

1. 組合符記。

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

1. 將已簽章的符記作為查詢參數附加至播放 URL。

   ```
   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>
   ```

## Node.js 範例
<a name="private-channels-tokens-nodejs-example"></a>

以下方法使用了 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;
}
```

在前端應用程式中，可以擷取此權杖並將其附加到私有頻道的播放 URL，如下所示。

```
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();
```