

# 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`e입니다. 이 필드 제외 시 기본값은 `false`입니다. 자세한 내용은 [서버 측 광고 삽입](https://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/server-side-ad-insertion.html)을 참조하세요.
  + `ads-player-params`는 선택적 필드로, 이를 사용하여 플레이어 파라미터인 것처럼 Elemental MediaTailor에 파라미터를 전달할 수 있습니다. 이 목록에 입력하는 키에는 항상 `player_params` 템플릿 파라미터가 네임스페이스로 지정됩니다. 모든 키와 값을 합친 총 페이로드 크기는 1,000바이트로 제한됩니다.
  + `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();
```