---
title: API에 인증된 요청을 보내기 위한 준비
description: JWT를 생성하고 서명하는 방법, OAuth2 플랫폼에 액세스 토큰을 요청하는 방법, 토큰 응답과 만료를 처리하는 방법.
canonical: https://developer.unico.io/ko/dual-api/developers/regional-solutions/card-not-present-verification/integration/authentication/preparing-authenticated-request
locale: ko
generated_by: markdown-export
---

서비스 계정을 생성하고 구성한 후, 애플리케이션은 다음 단계를 완료해야 합니다.

1. 헤더, 페이로드, 서명을 포함하는 JSON Web Token(JWT)을 생성합니다;
2. OAuth2 인증 플랫폼에 액세스 토큰(`AccessToken`)을 요청합니다;
3. 인증 플랫폼이 반환하는 JSON 응답을 처리합니다.

응답에 액세스 토큰이 포함되어 있으면, 서비스 계정이 접근 권한을 가진 Unico 제품 API에 요청할 때 이를 사용할 수 있습니다. (응답에 액세스 토큰이 포함되지 않은 경우, JWT와 토큰 요청이 잘못되었거나 서비스 계정이 요청한 리소스에 접근하는 데 필요한 권한을 갖고 있지 않을 수 있습니다.)

위 요청에서 생성된 액세스 토큰의 기본 유효 기간은 3600초이지만, 회사에 설정된 보안 구성에 따라 달라질 수 있습니다. 액세스 토큰이 만료되면 애플리케이션은 새로운 JWT를 생성하고 서명한 후 인증 플랫폼에 새 액세스 토큰을 요청해야 합니다.

### 1 — JWT 생성

JWT는 **헤더**, **페이로드**, **서명**의 세 부분으로 구성됩니다. 헤더와 페이로드는 JSON 객체입니다. 이 JSON 객체는 UTF-8로 직렬화된 후 **Base64url** 인코딩¹을 사용하여 인코딩됩니다. 이 인코딩 방식은 반복적인 인코딩 작업이 이루어지는 경우에도 인코딩 변경에 대한 내성을 제공합니다. 헤더, 페이로드, 서명은 마침표(`.`) 문자로 연결됩니다.

JWT는 다음과 같이 구성됩니다.

```
{Header in Base64url}.{Payload in Base64url}.{Signature in Base64url}
```

서명을 위한 기본 텍스트는 다음과 같이 구성됩니다.

```
{Header in Base64url}.{Payload in Base64url}
```

#### 1.1 — JWT 헤더 구성

헤더는 서명 알고리즘과 토큰 형식을 지정하는 두 개의 필드로 구성됩니다. 두 필드 모두 필수이며, 각 필드는 하나의 값만 가집니다. 서비스 계정은 RSA SHA-256 알고리즘과 JWT 토큰 형식을 사용합니다. 따라서 헤더의 JSON 표현은 다음과 같습니다.

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

Base64url 표현은 다음과 같습니다.

```
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
```

#### 1.2 — JWT 페이로드 구성

JWT 페이로드에는 요청된 권한(스코프), 접근을 요청하는 계정, 발급자, 토큰이 발급된 시각, 토큰의 수명 등 JWT에 대한 정보가 포함됩니다. 대부분의 필드는 필수입니다. JWT 헤더와 마찬가지로 페이로드도 JSON 객체이며 서명 구성에 사용됩니다.

#### 1.3 — 필수 필드

JWT의 필수 필드는 아래 표에 나와 있습니다. 페이로드 내에서 순서는 상관없습니다.

| 이름 | 설명 |
|---|---|
| `iss` | 회사 내 서비스 계정의 식별자입니다. |
| `scope` | 애플리케이션이 요청하는 권한의 목록으로, 공백 또는 더하기 기호(`+`)로 구분합니다. 계정의 모든 권한이 필요한 경우 별표(`*`) 기호를 사용하세요. |
| `aud` | 액세스 토큰을 발급하는 인증 플랫폼의 주소입니다. 이 값은 항상 정확히 `https://identityhomolog.acesso.io`여야 합니다. **작동하지 않는** 일반적인 문제: 끝에 슬래시를 추가하는 경우(`https://identityhomolog.acesso.io/`), 또는 HTTPS 대신 HTTP를 사용하는 경우. |
| `exp` | 토큰의 만료 시간으로, 1970년 1월 1일 00:00:00 UTC 이후 경과한 초 단위로 지정합니다. 이 값은 JWT 발급 시각으로부터 최대 1시간까지만 유효할 수 있습니다. 반드시 **숫자**여야 합니다 — `"1524161193"`처럼 따옴표로 묶인 값은 문자열이므로 작동하지 않으며, `1524161193`은 숫자이므로 작동합니다. |
| `iat` | JWT 발급 시각으로, 1970년 1월 1일 00:00:00 UTC 이후 경과한 초 단위로 지정합니다. 이 값은 `exp`와 동일한 규칙에 따라 **숫자**여야 합니다. |

`iat` 필드는 요구되는 형식으로 현재 시각을 나타내야 하며, `exp` 필드는 다음 계산식을 따라야 합니다.

```
exp = iat + 3600
```

JWT 페이로드에서 필수 JSON 필드의 표현은 다음과 같습니다.

```json
{
  "iss": "service_account_name@tenant_id.iam.acesso.io",
  "aud": "https://identityhomolog.acesso.io",
  "scope": "*",
  "exp": 1626296976,
  "iat": 1626293376
}
```

#### 1.4 — 서명 계산

**JSON Web Signature(JWS)**² 사양은 JWT 서명 계산을 안내하는 메커니즘입니다. 서명 계산을 위한 입력 콘텐츠는 다음 내용의 바이트 배열입니다.

```
{Header in Base64url}.{Payload in Base64url}
```

서명 계산에는 JWT 헤더에 지정된 것과 동일한 알고리즘을 사용해야 합니다. OAuth2 인증 플랫폼이 지원하는 유일한 서명 알고리즘은 SHA-256을 사용하는 RSA이며, JWT 헤더의 `alg` 필드에서는 `RS256`으로 표현됩니다.

서비스 계정에 대해 생성되고 연결된 개인 키(이메일로 받은 요청에서 생성된 `.key.pem` 파일)를 사용하여, SHA256withRSA(SHA-256 해시를 사용하는 RSASSA-PKCS1-V1_5-SIGN이라고도 함)로 입력 콘텐츠의 UTF-8 표현에 서명하세요. 출력 콘텐츠는 바이트 배열이 됩니다.

그런 다음 서명을 Base64url로 인코딩해야 합니다. 헤더, 페이로드, 서명은 마침표 문자로 연결되어야 합니다. 그 결과가 JWT입니다.

이미 만들어진 라이브러리를 사용하여 JWT를 생성할 수도 있습니다. 참고로 [jwt.io](https://jwt.io/) 웹사이트에서 라이브러리 목록을 확인할 수 있습니다.

### 2 — 액세스 토큰 요청하기

서명된 JWT를 생성한 후, 애플리케이션은 이를 사용하여 액세스 토큰을 요청할 수 있습니다. 액세스 토큰 요청은 POST HTTPS 요청이며, 본문은 URL 인코딩되어야 합니다. URL은 아래와 같습니다.

```
https://identityhomolog.acesso.io/oauth2/token
```

다음 파라미터는 POST HTTPS 요청에서 필수입니다.

| 이름 | 설명 |
|---|---|
| `grant_type` | 다음 텍스트를 사용하며, 필요한 경우 URL 인코딩합니다: `urn:ietf:params:oauth:grant-type:jwt-bearer` |
| `assertion` | 서명을 포함한 JWT입니다. |

```
POST /oauth2/token HTTP/1.1
Host: identityhomolog.acesso.io
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=<jwt>
```

### 3 — 인증 플랫폼 응답 처리하기

JWT와 액세스 토큰 요청이 올바르게 구성되어 있고 서비스 계정이 필요한 권한을 가지고 있다면, 인증 플랫폼은 액세스 토큰을 포함하는 JSON 객체를 반환합니다.

```json
{
  "access_token": "<access_token>",
  "token_type": "Bearer",
  "expires_in": "3600"
}
```

JSON 객체의 `access_token` 필드에 반환되는 액세스 토큰 역시 JWT 토큰이며, Unico 제품의 API에서 사용해야 합니다. 요청 중 오류가 발생하면 [인증 오류](./additional-resources/authentication-errors)에서 오류 유형을 확인하세요.

### 4 — 액세스 토큰의 유효 기간

액세스 토큰의 유효 기간은 가변적입니다. 유효 기간은 액세스 토큰과 함께 반환되는 `expires_in` 필드에 지정됩니다. 동일한 액세스 토큰은 유효 기간 동안 제품에 대한 모든 API 호출에서 계속 사용해야 합니다.

**현재 토큰의 유효 기간이 거의 끝날 때까지 새 액세스 토큰을 요청하지 마세요.** 600초(10분)의 여유를 두는 것을 권장합니다.

```
new Date((token.exp - 600) * 1000)
```

여기서 `token.exp`는 토큰 만료 시각의 타임스탬프입니다.

:::note
기본적으로 회사에 전송되는 토큰의 유효 기간은 1시간이지만 변경할 수 있습니다. 항상 `expires_in`을 기준으로 삼고 여기서 600초를 뺀 시점에 새 토큰을 요청하는 것을 권장합니다.
:::

**예시:**

```
Standard scenario:
expires_in: 3600 (1h) - Token generated at 14:42
Request a new token only at 15:32, that is, 14:42 + (3600 - 600)
```

```
Scenario with modified duration:
expires_in: 7200 (2h) - Token generated at 14:42
Request a new token only at 16:32, that is, 14:42 + (7200 - 600)
```

:::warning
**현재 토큰의 유효 기간이 설정된 시간보다 짧을 수 있으므로, 고정된 시간을 기준으로 새 토큰을 얻지 마세요. 이는 서비스 이용 중 실패를 유발할 수 있습니다.**
:::

---

¹ BaseN 인코딩에 대한 RFC 4648에 따르면, Base64url 형식은 Base64와 유사하지만 `=` 문자가 생략되고 `+`와 `/` 문자가 각각 `-`와 `_`로 대체된다는 차이가 있습니다.
² JSON Web Signature: [https://tools.ietf.org/html/rfc7515](https://tools.ietf.org/html/rfc7515).