# 보안 토큰

CDN 서비스 에서는 인증 방법으로 보안 토큰을 사용합니다. 본 장에서는 클레임(Claim) 기반의 JWT(Json Web Token)를 사용하여 보안 토큰을 생성하고, 전달하는 방법에 대해 설명합니다.

{% tabs %}
{% tab title="<클레임>" %}
보안 토큰에 정의되어 있는 개별 정보를 클레임(Claim)이라고 부르며, 클레임 이름(Claim Name)과 클레임 값(Claim Value)이 key-value 쌍으로 구성되어 있습니다.
{% endtab %}
{% endtabs %}

## JWT(Json Web Token) <a href="#toc460853028" id="toc460853028"></a>

JWT는 JSON 형식으로 기술한 클레임 기반의 데이터 전송 표준 규약입니다. 자세한 설명은 아래 사이트를 참고하시길 바랍니다.

* 참고사이트

{% tabs %}
{% tab title="<http://jwt.io>" %}
[http://jwt.io](http://jwt.io/) 에서는 웹 페이지에서 토큰을 생성∙검증할 수 있고, 개발 언어 별 라이브러리 정보를 제공합니다.
{% endtab %}

{% tab title="\<RFC 7519>" %}
<https://tools.ietf.org/html/rfc7519>
{% endtab %}
{% endtabs %}

## 전달 방법✅ <a href="#toc460853029" id="toc460853029"></a>

보안 토큰은 HTTP 쿼리 파라미터로 전달되고, 만료 시간(exp), 인증 경로(path) 등의 정보를 포함하고 있습니다. 아래는 인증 URL에 대한 예시입니다.

{% hint style="info" %}
<스트리밍 서비스>

스트리밍 서비스에서의 전달 방법은 부록 “[프로토콜에 따른 전달 방법](/secure_token/undefined.md#_toc460853042)” 절을 참고하시길 바랍니다.
{% endhint %}

**기본적인 인증 URL의 예.**

* 콘텐트 경로: /foo/sample.mp4
* 보안 토큰: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjI0ODA3ODMwLCJwYXRoIjoiL2Zvby9zYW1wbGUubXA0In0.NSO1VgouVfQBpJLlGZsk4r466wz6ba3weOm2Ba4VVUI
* 만료시간(exp): 16624807830
* 인증 경로(path): "/foo/sample.mp4"

> eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjI0ODA3ODMwLCJwYXRoIjoiL2Zvby9zYW1wbGUubXA0In0.NSO1VgouVfQBpJLlGZsk4r466wz6ba3weOm2Ba4VVUI

## 구조와 생성 <a href="#toc460853030" id="toc460853030"></a>

보안 토큰의 구조는 헤더(Header), 페이로드(Payload), 서명(Signature) 세 부분으로 구성되어 있습니다.

<figure><img src="/files/hW7EWiKZmvgGFxlBJWoa" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
<토큰 생성 예제>

JWT 라이브러리(Java, PHP)를 사용하여 토큰을 생성하는 방법은 아래 “[토큰 생성 예제](/secure_token/undefined.md)”를 참고하세요.
{% endhint %}

### JOSE(JSON Object Signing and Encryption) 헤더 <a href="#toc460853031" id="toc460853031"></a>

헤더는 토큰을 어떻게 해석해야 하는지 명시한 부분으로 알고리즘과 데이터 타입을 정의합니다.

```json
{
    "alg": "HS256",
    "typ": "JWT"
}
```

<table><thead><tr><th width="123">Key</th><th width="263">설명</th><th>Value</th></tr></thead><tbody><tr><td>alg</td><td>서명(Signature) 생성시에 사용한 알고리즘을 정의.</td><td><ul><li><p>HS256</p><ul><li>현재는 SHA-256 알고리즘만 지원합니다.</li></ul></li></ul></td></tr><tr><td>typ</td><td>클레임의 표현 형식을 정의.</td><td><ul><li><p>JWT</p><ul><li>현재 는 JWT 형식만 지원합니다.</li></ul></li></ul></td></tr></tbody></table>

### 페이로드(Payload) <a href="#toc460853032" id="toc460853032"></a>

페이로드가 포함하고 있는 모든 클레임을 클레임 셋(Claim Set)이라고 부릅니다.

```json
{
    "exp": 16624807830,
    "path":"/foo/sample.mp4",
    "playstart": 0,
    "duration": 180
}
```

<table><thead><tr><th width="131">Key</th><th width="248">설명</th><th>Value</th></tr></thead><tbody><tr><td>exp</td><td>만료 시간(Expiration Time)</td><td><ul><li><p>만료시간</p><ul><li>" 가포함되면 인증 실패가 <br>발생할 수 있습니다.</li></ul></li></ul></td></tr><tr><td>path</td><td>클레임의 표현 형식을 정의.</td><td><ul><li><p>인증 경로(Path)</p><ul><li>(/)를 포함한 디렉터리 또는, 콘텐트 파일의 실제 경로를 의미합니다. 인증 경로가 디렉터리 일 경우에는 하위 경로에 대한 접근 권한도 포함합니다.</li></ul></li></ul></td></tr><tr><td>playstart</td><td>재생 시작 시간(초)으로 VOD 서비스에서만 지원합니다.</td><td><ul><li>재생 시작 시간(초)</li></ul></td></tr><tr><td>duration</td><td>재생 시간(초)으로 라이브, VOD 서비스에서 지원합니다.</td><td><ul><li>재생 시간(초)</li></ul></td></tr></tbody></table>

{% hint style="info" %}
<스트리밍 서비스>

스트리밍 서비스는 인증 경로에 가상 파일을 포함하지 않도록 주의해야 합니다. 가상 파일에 대한 설명은 부록 부록의 “[가상 파일(Virtual file)](/secure_token/undefined.md#_toc460853041)”을 참고하세요.
{% endhint %}

### 서명(Signature) <a href="#toc460853033" id="toc460853033"></a>

토큰은 헤더와 페이로드를 위∙변조 할 수 없도록 반드시 보안-키(Secure Key)를 사용하여 SHA-256 알고리즘으로 서명해야 합니다.

#### <보안-키>

비밀 키(Secret Key)라고도 불리며, CDN과 콘텐트 제공자(Content Provider)간의 보안 채널을 생성하기 위해서 미리 공유하는 키입니다.

<figure><img src="/files/LGobVgJP86STt88tN1nM" alt=""><figcaption><p>Signing. (출처: http://100bytes.com/tutorials/security/jwt/json-web-signature)</p></figcaption></figure>

### 서명에 대한 예시 <a href="#toc460853034" id="toc460853034"></a>

아래는 서명 방법을 예시를 통해 설명합니다.

* 헤더와 페이로드를 각각 BASE64로 인코딩(Encoding)합니다.

<table><thead><tr><th width="140">데이터</th><th width="233">문자열</th><th>BASE64 인코딩</th></tr></thead><tbody><tr><td><strong>헤더</strong></td><td><p><em>{</em></p><p><em>"alg": "HS256",</em></p><p><em>"typ": "JWT"</em></p><p><em>}</em></p></td><td><mark style="color:red;">eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9</mark></td></tr><tr><td><strong>페이로드</strong></td><td><p><em>{</em></p><p><em>"exp":</em> 16624807830<em>,</em></p><p><em>"path": "/foo/sample.mp4"</em></p><p><em>}</em></p></td><td><mark style="color:orange;">eyJleHAiOjE2NjI0ODA3ODMwLCJwYXRoIjoiL2Zvby9zYW1wbGUubXA0In0</mark></td></tr></tbody></table>

{% hint style="warning" %}
BASE64 인코딩 문자열은 URL-Safe를 보장하고, 패딩(padding)은 제거해야 합니다.
{% endhint %}

* 마침표(.)를 구분 자로 사용하여 헤더와 페이로드를 연결합니다.

> <mark style="color:red;">eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.</mark>
>
> <mark style="color:orange;">eyJleHAiOjE2NjI0ODA3ODMwLCJwYXRoIjoiL2Zvby9zYW1wbGUubXA0In0</mark>

* 마지막으로 위의 문자열을 보안-키(Secure key)와 함께 SHA-256 알고리즘으로 해시 값을 추출합니다.

> *HMACSHA256(*
>
> *“*&#x65;yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjI0ODA3ODMwLCJwYXRoIjoiL2Zvby9zYW1wbGUubXA0In&#x30;*”,*
>
> *<mark style="color:red;">Secure Key</mark>*
>
> *)*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://manual.ktcdn.co.kr/secure_token/secure_token.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
