Langsung ke Solusi: Kontrak API Auth yang Aman untuk Retry

Untuk menjamin retry aman dan idempoten pada API autentikasi, kontrak harus menetapkan struktur yang ketat untuk issuing atau refresh token, kontrol header/body, status, error enum, serta webhook callback. Penjelasan berikut membahas kontrak tersebut secara teknis dan praktis, sehingga tim backend maupun klien dapat mengimplementasikan ulang dengan prediktabilitas.

1. Risiko Retry pada Endpoint Auth

Permintaan ulang (retry) sering terjadi karena latency, time-out, atau gangguan jaringan. Jika tidak didesain dengan idempoten, klien bisa menerima token ganda, sesi tak terkendali, atau validasi refresh yang kacau setelah mengirim ulang request.

Kontrak yang tepat harus mendefinisikan:

  • Header kontrol seperti X-Request-Id untuk deteksi duplikasi.
  • Payload identitas termasuk grant_type, client_id, dan nonce.
  • Status dan response code yang konsisten terhadap retry.
  • Error enum yang bisa dipakai klien untuk keputusan otomatis (retry, abort, refresh).

2. Struktur Request dan Response

Misalnya endpoint POST /oauth/token pada issuing token harus memuat body JSON sebagai berikut:

{
  "grant_type": "refresh_token",
  "refresh_token": "",
  "nonce": "uuid-v4"
}

Header wajib mencakup Content-Type: application/json dan X-Request-Id unik untuk setiap percobaan tingkat klien. Respon sukses menyertakan token_type, access_token, issued_at, dan retry_after yang memberi tahu klien kapan bisa mencoba lagi.

Contoh respons:

{
  "access_token": "eyJhb...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "issued_at": 1700000000,
  "retry_after": null
}

Jika retry masih diperbolehkan (contoh: backend melakukan pemrosesan asinkron), retry_after bisa berisi delay yang direkomendasikan.

3. Pengendalian Status dan Error Enum

Gunakan status HTTP konsisten:

  • 200/201 untuk keberhasilan.
  • 202 bila token sedang diproses dan klien diminta retry setelah retry_after.
  • 400 untuk kesalahan payload.
  • 409 untuk deteksi duplikat request (terikat X-Request-Id).
  • 429 jika rate limit tercapai.

Error enum memudahkan logika klien, contoh:

{
  "error": "duplicate_request",
  "error_description": "X-Request-Id 123 sudah diproses"
}

Enum lainnya: invalid_grant, expired_refresh, rate_limited. Klien harus memetakan masing-masing ke aksi spesifik.

4. Deteksi Duplikasi dan Verifikasi Signature

Kontrak harus menjelaskan bagaimana backend mendeteksi request ganda:

  • Tokenisasi X-Request-Id di layer middleware, disimpan bersama status pending/completed.
  • Jika request dengan ID sama datang sementara status pending, server mengembalikan 202 dengan pointer ke job asynchronous.

Verifikasi signature diperlukan pada payload jika client mengirimkan assertion (misalnya JWT client assertion). Kontrak harus menyebutkan:

  • Header yang dipakai untuk signature (Authorization: Bearer untuk token akses, X-Signature untuk payload).
  • Algoritma yang digunakan (misalnya HMAC-SHA256) sebagai opsi.
  • Skema fallback saat verifikasi gagal (return 401 + invalid_signature enum).

5. Webhook Callback untuk Penyelesaian Token

Jika issuing token memerlukan proses latensi tinggi (misal pending approval), kontrak perlu mendefinisikan webhook callback:

  • Endpoint webhook wajib menggunakan HTTPS.
  • Payload callback mencakup request_id, status, dan token jika sukses.
  • Signature callback memvalidasi integritas, biasanya dengan header X-Callback-Signature.

Contoh payload:

{
  "request_id": "req-123",
  "status": "completed",
  "access_token": "eyJhb..."
}

Klien harus menyimpan request_id untuk mencocokkan callback dan memperbarui UI/worker.

6. Pola Backoff dan Timeout

Kontrak harus menjelaskan cara klien menangani retry:

  • Gunakan exponential backoff terbatas dengan jitter untuk menghindari thundering herd.
  • Set timeout total yang konsisten (misal 30 detik) agar tidak menunggu selamanya.
  • Jika server mengembalikan retry_after, sesuaikan backoff dengan nilai tersebut.

Backoff terbaik menyediakan batas atas dan restart counter setelah respons sukses. Dokumentasikan parameter ini agar klien dan backend sejalan.

7. Dokumentasi dan Validasi Kontrak Antar Tim

Berikut langkah konkret dokumentasi dan validasi:

  1. Tulis kontrak menggunakan OpenAPI/JSON Schema dengan contoh request, response, status code, dan enum error.
  2. Gunakan contract testing (misal Pact) untuk memastikan mock backend memenuhi spesifikasi.
  3. Integrasikan linting schema ke pipeline CI agar perubahan kontrak tergantung persetujuan lintas tim.
  4. Publish changelog kontrak—setiap penambahan field atau header harus dideklarasikan dengan versi dan kompatibilitas.

Tambahkan bagian FAQ yang menjelaskan pola retry, fallback, dan verifikasi signature.

8. Diagram Urutan dan Checklist Kualitas

Berikut diagram urutan menggambarkan alur retry:

Client -> AuthAPI: POST /oauth/token (X-Request-Id)
AuthAPI -> TokenService: validasi signature dan nonce
TokenService -> DB: cek request_id (pending/completed)
alt request_id baru
  TokenService -> AuthAPI: proses issuing token
  AuthAPI -> Client: 200 + token
else duplicate
  AuthAPI -> Client: 409 + error enum duplicate_request
end
Client -> AuthAPI: retry setelah backoff (jika bisa)

Checklist untuk kontrak API:

  • Apakah X-Request-Id dan error enum didefinisikan?
  • Apakah status HTTP konsisten untuk retry dan duplikat?
  • Apakah retry_after atau webhook callback tersedia untuk proses panjang?
  • Apakah payload webhook memuat signature yang dapat diverifikasi?
  • Apakah dokumentasi kontrak tersedia dan divalidasi otomatis?
  • Apakah backoff dijelaskan dan batas timeout jelas?

Kesimpulan

Kontrak API Auth untuk issuing/refresh token harus mendefinisikan header/body, status, error enum, webhook callback, pola backoff, deteksi duplikasi, dan verifikasi signature agar retry berjalan aman dan idempoten. Dokumentasi lintas tim serta validasi otomatis memastikan semua pihak menjaga konsistensi kontrak dan dapat menangani kesalahan atau perubahan tanpa mengorbankan keamanan.