# 인증 및 서명

Weydub API 요청은 `AppKey` 및 `AppSign` 헤더를 사용합니다. `AppSecret`는 서버 측에만 보관하십시오.

## 요청 구조

| 항목 | 값 |
| --- | --- |
| 기본 URL | `https://api.zhaoli.com` |
| 프로토콜 | HTTPS |
| 메서드 | 문서화된 API 호출에는 `POST` |
| 인코딩 | UTF-8 |
| 콘텐츠 유형 | `application/json` |
| 요청 본문 | 안정적인 서명을 위해 간결하게 직렬화된 JSON |

## 헤더

```text
Content-Type: application/json
AppKey: your_app_key
AppSign: computed_signature
```

`AppSecret`는 헤더나 본문 필드로 절대 전송되지 않습니다. 서버에서 `AppSign`을 계산할 때만 사용됩니다.

## 서명 공식

```text
AppSign = md5(md5(request_body) + AppSecret)
```

서명은 네트워크를 통해 전송되는 정확한 JSON 본문을 기준으로 계산해야 합니다. 안정적인 서명을 위해 추가 공백 없이 JSON을 직렬화하십시오.

엔드포인트에서 빈 본문을 허용하는 경우 전송하는 정확한 바이트에 서명하십시오. 대부분의 통합에서는 본문이 없는 호출에 `{}`을 전송하고 `{}`에 서명하는 것이 좋습니다.

## 서명이 필요 없는 엔드포인트

enum 엔드포인트에는 서명이 필요하지 않습니다:

```text
POST /v-w-c/enum/query2
```

이를 사용하여 `sourceLang`, `Lang`, `ProcessStatus` 및 `ImageTaskStatus`과 같은 동적 언어/상태 enum을 가져오십시오.

## Python 서명 헬퍼

```python
import hashlib
import json


def signed_body_and_headers(payload: dict, app_key: str, app_secret: str):
    body = json.dumps(payload, ensure_ascii=False, separators=(",", ":"))
    body_md5 = hashlib.md5(body.encode("utf-8")).hexdigest()
    app_sign = hashlib.md5((body_md5 + app_secret).encode("utf-8")).hexdigest()
    return body, {
        "Content-Type": "application/json",
        "AppKey": app_key,
        "AppSign": app_sign,
    }
```

## Node 서명 헬퍼

```js
import crypto from "node:crypto";

export function signedBodyAndHeaders(payload, appKey, appSecret) {
  const body = JSON.stringify(payload);
  const bodyMd5 = crypto.createHash("md5").update(body).digest("hex");
  const appSign = crypto.createHash("md5").update(bodyMd5 + appSecret).digest("hex");
  return {
    body,
    headers: {
      "Content-Type": "application/json",
      AppKey: appKey,
      AppSign: appSign,
    },
  };
}
```

## cURL 패턴

백엔드를 사용하여 `AppSign`을 계산한 다음 정확한 본문을 전송하십시오:

```bash
curl -X POST "https://api.zhaoli.com/v-w-c/gateway/ve/work/status" \
  -H "Content-Type: application/json" \
  -H "AppKey: $WEYDUB_APP_KEY" \
  -H "AppSign: $WEYDUB_APP_SIGN" \
  --data '{"idWorks":[488026661]}'
```

## 콜백 서명

Weydub가 콜백을 전송할 때 다음을 포함합니다:

```text
Callback-Sign: computed_callback_signature
```

원시 콜백 요청 본문을 사용하여 동일한 공식으로 콜백을 검증하십시오:

```text
expected = md5(md5(raw_callback_body) + AppSecret)
```

`expected`을 `Callback-Sign`과 비교하십시오. 검증에 실패한 콜백 페이로드는 거부하거나 격리하십시오.

## 일반적인 실수

- 가독성 있게 서식 지정된 JSON에 서명하고 간결한 JSON을 전송하는 경우.
- 서명한 후 페이로드를 변경하는 경우.
- 서명할 때와 전송할 때 서로 다른 문자열 이스케이프를 사용하는 경우.
- HTTP을 통해 전송되는 최종 바이트 대신 메모리의 객체에 서명하는 경우.
- `extraOptions`, `wyVoiceParam`, `videoInpaintMasks`, `downloadInfo` 및 redo `result`가 외부 JSON 본문 내부에서 간결한 JSON 문자열로 유지되어야 할 수 있다는 점을 잊는 경우.
- 프런트엔드 코드에 자격 증명을 넣는 경우.
- 브라우저 확장 프로그램, 클라이언트 측 앱, 스크린샷, 로그 또는 공개 프롬프트에 `AppSecret`을 공유하는 경우.

## 에이전트 규칙

- 환경 변수 또는 시크릿 관리자로부터 자격 증명을 읽으십시오.
- `AppSecret`을 절대 출력하지 마십시오.
- 생성된 샘플 파일에 자격 증명을 절대 작성하지 마십시오.
- 실행 가능한 예제를 작성할 때는 플레이스홀더 또는 환경 변수를 사용하십시오.
- 서명 오류를 디버깅할 때는 시크릿을 출력하지 말고 본문 바이트와 시크릿이 아닌 본문 해시를 비교하십시오.
- 웹훅 핸들러에서 `Callback-Sign`을 검증하십시오.
