> ## Documentation Index
> Fetch the complete documentation index at: https://make.edicus.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 토큰과 API 키

> 두 자격 증명이 각각 무엇을 할 수 있고 어디에 두어야 하는지

Edicus 연동에는 자격 증명이 두 가지 있습니다. 둘을 헷갈리면 보안 사고가 나거나 편집기가 뜨지 않습니다.

| | API 키 | 토큰 |
| - | - | - |
| 헤더 이름 | `edicus-api-key` | 편집기 URL의 `token` 파라미터 |
| 두는 곳 | **고객사 서버에만** | 브라우저 |
| 할 수 있는 것 | 그 파트너의 모든 사용자와 프로젝트, 주문 | 그 사용자 한 명으로 편집기에 인증 |
| 유효기간 | 없음 | 1시간 |
| 발급처 | 모션원 | API 키로 Edicus 서버에 요청 |

<Danger>
  API 키는 브라우저 코드, 공개 저장소, 프런트엔드 환경변수(`NEXT_PUBLIC_*`, `VITE_*` 등)에 절대 넣지 않습니다. 이 키 하나로 그 파트너의 전체 데이터에 접근할 수 있습니다.
</Danger>

## API 키

모션원에서 파트너별로 발급합니다. Server API의 모든 요청에 `edicus-api-key` 헤더로 보냅니다.

```ts theme={null}
headers: {
  'edicus-api-key': process.env.EDICUS_API_KEY!,
}
```

Edicus는 서버용 JS SDK를 제공하지 않습니다. 서버 연동은 이 헤더를 붙여 HTTP로 직접 호출합니다. 호출을 한 곳에 모아 두는 방법은 [Server API 호출하기](/docs/server/client)에 있습니다.

## uid

`uid`는 고객사가 자기 사용자에게 부여하는 고유 id입니다. Edicus는 이 값으로 프로젝트의 소유자를 구분합니다.

<ParamField path="uid" type="string" required>
  고객을 특정할 수 있고, 중복되지 않고, 바뀌지 않는 값이어야 합니다.
</ParamField>

형식 규칙이 있습니다.

* **1자 이상 70자 이하**여야 합니다.
* 허용 문자: `a-z`, `A-Z`, `0-9`, `_`, `!`, `@`, `-`, `+`, `=`
* 그 밖의 문자는 쓸 수 없습니다. `.`, `#`, `$`, `[`, `]`, 공백, 그리고 **`/`와 `\`** 도 마찬가지입니다.

규칙을 어긴 `edicus-uid`를 보내면 토큰 발급뿐 아니라 사용자 단위 요청 전부가 `400 invalid_request`로 거절됩니다. 복제할 때 쓰는 `edicus-target-uid`도 같은 규칙을 따릅니다.

예: `kr46KCD8vWOnOGo8CBO7c6ctSge2`

<Note>
  `uid`는 별도의 생성 절차가 없습니다. 처음 보는 값으로 토큰을 요청하면 그 순간 사용자가 만들어집니다. 고객사 사용자 DB의 계정과 1:1로 대응하는 값을 쓰세요.
</Note>

<Warning>
  **개인정보를 그대로 쓰지 마세요.** 이메일 주소, 전화번호, 주민등록번호, 로그인 아이디 같은 값을 `uid`로 넘기면 그 값이 Edicus 쪽에 사용자 식별자로 그대로 남습니다. UUID처럼 내부에서만 의미를 갖는 식별자를 쓰세요.

  바뀔 수 있는 값도 피합니다. `uid`가 바뀌면 그 사용자가 만든 프로젝트에 접근할 수 없게 됩니다. 이메일 주소는 개인정보인 동시에 바뀔 수 있는 값이고 `.`까지 포함하고 있어 세 가지 이유로 부적합합니다.
</Warning>

## 토큰

`uid`를 기반으로 만들어진 JWT입니다. 브라우저에서 편집기를 띄울 때 씁니다.

```ts theme={null}
const res = await fetch('https://api.edicus.io/v2/auth/token', {
  method: 'POST',
  headers: {
    'edicus-api-key': process.env.EDICUS_API_KEY!,
    'edicus-uid': user.edicusUid,
  },
})
if (!res.ok) {
  const { error } = await res.json()
  throw new Error(`토큰 발급 실패: ${error.code} (${error.request_id})`)
}
const { token } = await res.json()
```

유효기간은 발급 후 1시간입니다. 다만 **이미 인증된 편집기 화면 자체는 로그아웃 전까지 계속 쓸 수 있습니다.** 토큰이 만료됐다고 편집 중이던 사용자가 갑자기 튕기지는 않습니다.

편집기가 갱신이 필요하다고 판단하면 `request-user-token` 이벤트를 보냅니다. 편집기는 저장 중 인증이 풀렸을 때(Storage 권한 오류) 이 이벤트를 보내고, 새 토큰으로 다시 로그인한 뒤 저장을 재시도합니다. 이벤트에는 `{ uid }`(파트너 코드가 앞에 붙은 사용자 id)가 실려 옵니다. 이때 새 토큰을 보내주면 됩니다.

<Warning>
  편집기는 `send-user-token` 응답을 **3초만** 기다립니다. 3초 안에 답이 없으면 그 저장은 실패합니다. 토큰 엔드포인트를 빠르게 유지하고, 오래 걸리는 처리를 그 앞에 두지 마세요.
</Warning>

### 토큰 자동 갱신

`createEdicusClient`에 `getToken`을 주면 SDK가 이 이벤트에 자동으로 응답합니다.

```ts theme={null}
const edicus = createEdicusClient({
  getToken: async () => (await fetch('/api/edicus/token').then((r) => r.json())).token,
})
```

<Warning>
  `getToken`이 돌려주는 토큰은 **처음 편집기를 띄울 때와 같은 `edicus-uid`로 발급한 토큰**이어야 합니다. 다른 uid의 토큰을 돌려주면 편집기가 로그아웃하고 작업을 멈춥니다. 토큰 엔드포인트가 로그인 세션에서 uid를 꺼내도록 만들고, 요청 파라미터로 uid를 받지 마세요.
</Warning>

`getToken`을 설정하면 `request-user-token`은 핸들러로 전달되지 않습니다. SDK가 소비하고 `send-user-token`으로 답합니다. 동시에 여러 요청이 와도 진행 중인 `getToken()` 호출 하나를 공유합니다. `getToken`이 reject하면 자동 응답을 포기하고 이벤트를 평소대로 전달하므로, 직접 처리할 기회가 남습니다.

<Note>
  이 자동 응답은 `EditorSession`에만 있습니다. TnView와 Preview 세션에는 없습니다.
</Note>

`getToken`을 쓰지 않는다면 직접 응답합니다.

```ts theme={null}
session.on('request-user-token', async () => {
  const { token } = await fetch('/api/edicus/token').then((r) => r.json())
  session.post('send-user-token', { token })
})
```

## 다음 단계

<Columns cols={2}>
  <Card title="설치와 진입점" icon="box" href="/docs/sdk/install">
    편집기 SDK의 임포트 경로를 봅니다.
  </Card>

  <Card title="Server API" icon="server" href="/docs/api-reference/introduction">
    토큰 발급 엔드포인트의 요청과 응답을 봅니다.
  </Card>
</Columns>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.