DOCS

Xác thực OAuth 2.0

Xác thực OAuth 2.0

Xác thực các dịch vụ phía sau của bạn với Zonos bằng cách sử dụng mã hóa khóa bất đối xứng — không cần bí mật chia sẻ.

Zonos hỗ trợ xác thực máy chủ sang máy chủ thông qua OAuth 2.0 JWT Bearer Token Grant (RFC 7523). Dịch vụ của bạn ký một JWT có thời gian sống ngắn bằng khóa riêng RSA của bạn; Zonos xác minh nó bằng cách sử dụng khóa công khai đã đăng ký của bạn và trả về một token Bearer được phân vùng theo tổ chức của bạn.

Tóm tắt luồng:

  1. Tạo một cặp khóa RSA và đăng ký khóa công khai của bạn với Zonos.
  2. Lúc chạy, ký một xác nhận JWT bằng khóa riêng của bạn và POST nó đến điểm cuối token.
  3. Zonos trả về một token truy cập có thời gian sống ngắn.
  4. Bao gồm token truy cập dưới dạng Authorization: Bearer <token> trên mỗi yêu cầu API.

Tạo cặp khóa RSA 4096-bit và chia sẻ khóa công khai với Zonos. Điều này được thực hiện một lần trong quá trình onboarding.

Tạo cặp khóa 

1# Generate private key
2openssl genrsa -out private_key.pem 4096
3 
4# Extract public key
5openssl rsa -in private_key.pem -pubout -out public_key.pem

Chia sẻ public_key.pem với Zonos. Lưu trữ private_key.pem trong trình quản lý bí mật chuyên dụng (AWS Secrets Manager, HashiCorp Vault, v.v.) — không bao giờ trong kiểm soát nguồn hoặc biến môi trường.

Zonos sẽ đăng ký khóa của bạn và trả về ID Tổ chức của bạn, trở thành yêu cầu iss trong tất cả các xác nhận JWT.

Ký một JWT bằng RS256 bằng cách sử dụng khóa riêng của bạn. Xác nhận có hiệu lực cho một lần trao đổi token duy nhất — giữ cửa sổ hết hạn ngắn (60–300 giây).

Yêu cầu các đòi hỏi 

Yêu cầuGiá trị
issID Tổ chức Zonos của bạn (ví dụ: "org_abc123")
subXác định dịch vụ gọi (ví dụ: "checkout-service")
audPhải chính xác "zonos-auth"
expDấu thời gian Unix; 60–300 giây từ iat
iatDấu thời gian Unix của cấp phát
jtiUUID duy nhất cho mỗi xác nhận (bật phát hiện phát lại)

Tiêu đề JWT phải chỉ định "alg": "RS256""typ": "JWT".

Ví dụ về mã 

1import jwt, uuid, time
2 
3with open("private_key.pem") as f:
4 private_key = f.read()
5 
6now = int(time.time())
7assertion = jwt.encode(
8 {
9 "iss": "org_abc123",
10 "sub": "checkout-service",
11 "aud": "zonos-auth",
12 "iat": now,
13 "exp": now + 300,
14 "jti": str(uuid.uuid4()),
15 },
16 private_key,
17 algorithm="RS256",
18)

Gửi JWT đã ký đến điểm cuối token Zonos để nhận token Bearer có thời gian sống ngắn.

Điểm cuối 

POST https://auth.zonos.com/oauth/token
Content-Type: application/json

application/x-www-form-urlencoded cũng được chấp nhận.

Trường yêu cầu 

TrườngBắt buộcGiá trị
grant_type"urn:ietf:params:oauth:grant-type:jwt-bearer"
assertionJWT đã ký của bạn (nén dạng tuần tự)

Yêu cầu và phản hồi 

1{
2 "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
3 "assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
4}
Trường phản hồiMô tả
access_tokenToken Bearer cho tất cả các yêu cầu API tiếp theo
token_typeLuôn "Bearer"
expires_inGiây cho đến khi hết hạn (mặc định: 300)
scopeCác quyền được cấp cho token này, được phân tách bằng dấu cách

Ví dụ mã đầy đủ 

1import requests
2 
3response = requests.post(
4 "https://auth.zonos.com/oauth/token",
5 json={
6 "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
7 "assertion": assertion,
8 },
9)
10data = response.json()
11access_token = data["access_token"]
12expires_in = data["expires_in"]

Bao gồm token truy cập dưới dạng token Bearer trong tiêu đề Authorization trên mỗi yêu cầu API Zonos.

Yêu cầu ví dụ 

1curl -X POST https://api.zonos.com/graphql \
2 -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
3 -H "Content-Type: application/json" \
4 -d '{ "query": "{ ... }" }'

Vòng đời token và bộ nhớ cache 

Token truy cập hết hạn trong 5 phút theo mặc định. Lưu trữ token trong bộ nhớ cache và làm mới một cách chủ động — không yêu cầu token mới trên mỗi lệnh gọi API. Mỗi lần làm mới yêu cầu một xác nhận JWT được ký lại.

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"]

Tham khảo lỗi 

Tất cả các lỗi tuân theo định dạng phản hồi lỗi OAuth 2.0 (RFC 6749 §5.2):

1{
2 "error": "invalid_grant",
3 "error_description": "JWT assertion has expired"
4}
Trạng thái HTTPerrorNguyên nhân
400unsupported_grant_typegrant_type không phải urn:ietf:params:oauth:grant-type:jwt-bearer
400invalid_requestTrường bị thiếu hoặc sai định dạng
401invalid_grantChữ ký không hợp lệ, xác nhận hết hạn, tổ chức không xác định hoặc khóa chưa đăng ký
500server_errorLỗi nội bộ — liên hệ hỗ trợ Zonos nếu kiên trì

Nguyên nhân phổ biến của invalid_grant:

  • exp nằm trong quá khứ — đảm bảo đồng hồ hệ thống của bạn được đồng bộ NTP
  • aud không chính xác "zonos-auth"
  • iss không khớp với ID Tổ chức đã đăng ký của bạn
  • Khóa công khai đã được xoay nhưng chưa được cập nhật với Zonos

Các thực hành bảo mật tốt nhất 

  • Bảo vệ khóa riêng của bạn. Lưu trữ nó trong trình quản lý bí mật chuyên dụng — không bao giờ trong kiểm soát nguồn, biến môi trường hoặc nhật ký.
  • Giữ xác nhận ngắn. 60–300 giây là tiêu chuẩn; không có lý do để phát hành những cái dài hơn.
  • Bao gồm jti. Một giá trị duy nhất cho mỗi xác nhận cho phép phát hiện phát lại phía máy chủ.
  • Xoay cặp khóa định kỳ. Đăng ký khóa công khai mới với Zonos trước khi thu hồi khóa cũ để tránh ngừng hoạt động.
  • Không bao giờ ghi nhật ký access_token hoặc assertion giá trị. Coi cả hai là thông tin xác thực.

Trang này có hữu ích không?