DOCS

OAuth 2.0 인증

비대칭 키 암호화 방식을 사용해 백엔드 서비스를 Zonos와 인증합니다 — 공유 비밀키가 필요 없습니다.

Zonos는 OAuth 2.0 JWT Bearer 토큰 부여(RFC 7523)를 통한 서버 간(machine-to-machine) 인증을 지원합니다. 서비스가 RSA 개인 키로 단기 유효 JWT에 서명하면, Zonos는 등록된 공개 키로 이를 검증하고 조직 범위로 한정된 Bearer 토큰을 반환합니다.

흐름 요약:

  1. RSA 키 페어를 생성하고 공개 키를 Zonos에 등록합니다.
  2. 실행 시점에 개인 키로 JWT assertion에 서명하고 토큰 엔드포인트로 POST합니다.
  3. Zonos가 단기 유효 액세스 토큰을 반환합니다.
  4. 모든 API 요청에 액세스 토큰을 Authorization: Bearer <token> 형식으로 포함합니다.

토큰 수명 및 캐싱 

액세스 토큰은 기본적으로 5분 후 만료됩니다. 토큰을 캐시하고 선제적으로 갱신하세요 — API를 호출할 때마다 새 토큰을 요청하지 마세요. 갱신할 때마다 새로 서명된 JWT assertion이 필요합니다.

1import time, requests
2 
3_cache = {"access_token": None, "expires_at": 0}
4 
5def get_access_token():
6 if time.time() < _cache["expires_at"] - 30:
7 return _cache["access_token"]
8 
9 assertion = build_jwt_assertion()
10 data = requests.post(
11 "https://auth.zonos.com/oauth/token",
12 json={
13 "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
14 "assertion": assertion,
15 },
16 ).json()
17 
18 _cache["access_token"] = data["access_token"]
19 _cache["expires_at"] = time.time() + data["expires_in"]
20 return _cache["access_token"]

오류 참조 

모든 오류는 OAuth 2.0 오류 응답 형식(RFC 6749 §5.2)을 따릅니다:

1{
2 "error": "invalid_grant",
3 "error_description": "JWT assertion has expired"
4}
HTTP 상태↕error↕원인↕
400unsupported_grant_typegrant_type이 urn:ietf:params:oauth:grant-type:jwt-bearer가 아님
400invalid_request필드가 누락되었거나 형식이 잘못됨
401invalid_grant서명이 유효하지 않거나, assertion이 만료되었거나, 알 수 없는 조직이거나, 키가 등록되지 않음
500server_error내부 오류 — 문제가 계속되면 Zonos 지원팀에 문의하세요

일반적인 invalid_grant 발생 원인:

  • exp가 과거 시점임 — 시스템 시계가 NTP로 동기화되어 있는지 확인하세요
  • aud가 정확히 "zonos-auth"가 아님
  • iss가 등록된 조직 ID와 일치하지 않음
  • 공개 키를 교체했지만 아직 Zonos에 업데이트하지 않음

보안 모범 사례 

  • 개인 키를 보호하세요. 전용 시크릿 관리 서비스에 저장하고, 소스 코드, 환경 변수, 로그에는 절대 두지 마세요.
  • assertion을 단기 유효하게 유지하세요. 60~300초가 표준이며, 그보다 길게 발급할 이유가 없습니다.
  • jti를 포함하세요. assertion마다 고유한 값을 사용하면 서버 측에서 재사용 공격을 탐지할 수 있습니다.
  • 키 페어를 주기적으로 교체하세요. 다운타임을 피하려면 기존 키를 폐기하기 전에 새 공개 키를 Zonos에 등록하세요.
  • access_token이나 assertion 값을 로그에 남기지 마세요. 둘 다 자격 증명(credential)으로 취급하세요.

이 페이지가 도움이 되었나요?