Langsung ke konten utama
Autentikasi adalah fitur baru. Setiap panggilan di halaman ini menggunakan kredensial pengguna akhir atau tidak sama sekali. Jangan pernah mengirim kunci API verifikasi atau token konsol Anda ke endpoint ini.
Setiap aplikasi adalah issuer OpenID Connect tersendiri. Issuer adalah origin login aplikasi Anda:
  • https://<name>.auth.didit.me untuk aplikasi produksi,
  • https://<name>.sandbox.auth.didit.me untuk aplikasi sandbox,
  • atau domain kustom Anda, setelah domain tersebut aktif.
Produksi dan sandbox adalah issuer terpisah dengan kunci terpisah. Atur DIDIT_AUTH_ISSUER ke issuer Anda, tanpa garis miring di akhir, dan DIDIT_APPLICATION_ID ke ID aplikasi Anda: token membawanya sebagai aud. Kunci yang dapat dipublikasikan menyandikan issuer: setelah pk_live_ atau pk_test_, terdapat issuer dalam base64url tanpa padding.
Ketika domain kustom Anda menjadi aktif, domain tersebut menggantikan host default sebagai issuer. Token baru menyebutkannya di iss, discovery mengarahkan jwks_uri ke domain tersebut, dan kunci yang dapat dipublikasikan Anda berubah. Token akses yang diterbitkan di bawah host default kemudian gagal pada GET /session/ hingga disegarkan. Perbarui DIDIT_AUTH_ISSUER saat Anda mengaktifkan domain, atau terima kedua issuer hingga token lama kedaluwarsa, dalam waktu 5 menit.
Endpoint server di halaman ini (discovery, kunci, token dan sesi) ada dalam referensi API Autentikasi, yang dibuat dari openapi-authentication.json. Halaman masuk yang di-hosting tidak termasuk.

Penemuan dan kunci

Issuer mendukung:
  • Response type code dan response mode query.
  • Grant type authorization_code dan refresh_token.
  • Metode PKCE S256 saja. Klien bersifat publik: tidak ada client secret, dan client_id adalah ID aplikasi Anda.
  • Algoritma penandatanganan ES256 (kunci P-256).
  • Scope openid, email, phone, profile dan offline_access.
Tidak ada endpoint userinfo, introspection, atau end-session, dan prompt=none tidak didukung. Gunakan GET /session/ untuk membaca dan memeriksa sesi.

Caching dan rotasi

Kedua dokumen merespons dengan Cache-Control: public, max-age=300, sehingga Anda dan cache bersama dapat menyimpannya selama 5 menit. Keduanya mengizinkan 1,200 permintaan per menit dan 12,000 per jam per alamat IP, jauh lebih tinggi daripada endpoint masuk, karena banyak instance backend sering berbagi satu alamat.
  • Setiap kunci memiliki kid; ID kunci baru dimulai dengan k_. Setiap token menyebutkan kuncinya di header kid.
  • Kunci diputar setiap 30 hari. Didit mempublikasikan kunci berikutnya satu hari sebelum mulai menandatangani, dan tetap mempublikasikan kunci sebelumnya selama satu hari setelah berhenti menandatangani. JWKS yang di-cache selama 5 menit oleh karena itu tetap dapat memverifikasi selama rotasi.
  • Simpan kunci di cache berdasarkan kid. Ketika sebuah token menyebutkan kid yang tidak Anda miliki, ambil ulang JWKS, paling banyak sekali per menit, dan tolak token jika kunci tersebut masih tidak ada.
  • Ketika Didit mencabut kunci yang disusupi, Didit segera menghapus kunci itu dari JWKS, dan GET /session/ menolak setiap token yang ditandatangani oleh kunci tersebut. Kunci pengganti langsung mulai menandatangani tanpa publikasi satu hari sebelumnya. JWKS yang di-cache hingga 5 menit sebelumnya masih menerima kunci yang dicabut dan belum mengenal kunci pengganti, sehingga token baru dapat gagal pada verifikasi offline hingga cache diperbarui.

Memulai login

Buka halaman yang di-hosting, yaitu authorization_endpoint:
Panduan mulai cepat membuat permintaan ini untuk Anda. Callback menerima code dan state. Periksa state, lalu tukarkan kode dalam 60 detik. Setiap kode hanya dapat digunakan sekali. Isi permintaan dapat berupa JSON atau dikodekan dalam format formulir.
expires_in menghitung sisa detik masa berlaku token akses. Saat Anda menonaktifkan banyak sesi, pertukaran ini mengakhiri sesi lain milik pengguna tersebut.

Klaim token akses

Token akses adalah JWT dengan header alg: ES256 dan typ: at+jwt. Masa berlakunya paling lama 5 menit, dan tidak pernah lebih lama dari sesinya. ID token memiliki header typ: JWT. Token ini memuat klaim yang sama kecuali client_id, ditambah auth_time dan email_verified, serta email, name dan phone_number jika memiliki nilai. Hanya ID token dari pertukaran kode yang memuat nonce, jika proses login memilikinya: periksa di sana, karena ID token dari refresh tidak pernah memuatnya. ID token tidak pernah diterima sebagai token akses.

Verifikasi token di server Anda

Periksa semua ini sebelum mempercayai klaim apa pun:
  1. alg bernilai ES256 dan typ bernilai at+jwt. Tolak algoritma lain, termasuk none.
  2. kid ada di JWKS aplikasi Anda, dan tanda tangannya terverifikasi.
  3. iss sama dengan penerbit yang Anda konfigurasi, dan aud sama dengan ID aplikasi Anda.
  4. exp dan iat valid, dengan toleransi perbedaan waktu hingga 60 detik, dan sub, sid serta jti harus ada.
  5. act bernilai null. Token akses agen AI ditandatangani dengan kunci yang sama dan memuat typ, iss dan aud yang sama; hanya act yang membedakannya. Tolak token tersebut, kecuali endpoint Anda menerima agen: dalam kasus itu, izinkan hanya tindakan yang diizinkan oleh act.scopes. GET /session/ selalu menolak token agen.
Ambil penerbit dari konfigurasi Anda, jangan pernah dari token.
Verifikasi offline tidak dapat melihat sesi yang baru saja berakhir. Jika hal itu penting, misalnya sebelum pencairan dana, panggil GET /session/.

Periksa sesi

Respons berisi sub, sid, application_id, vendor_data, amr, mfa_verified, email, email_verified, phone, verified_identity, verified, expires_at, post_logout_redirect_uri dan organizations. Setiap entri organisasi memiliki organization_id, organization__name, role dan custom_role. Pemeriksaan ini lebih ketat daripada verifikasi offline. Pemeriksaan ini juga gagal jika sesi dicabut, menjadi tidak aktif, atau melewati masa berlakunya; jika orang tersebut diblokir atau emailnya tidak lagi terverifikasi; jika sesi tidak lagi memenuhi kebijakan MFA Anda (misalnya setelah orang tersebut menambahkan aplikasi authenticator atau menjadi admin organisasi); atau jika token telah diganti oleh refresh. Jika gagal, respons 401 {"detail": "invalid_token"} dengan WWW-Authenticate: Bearer dikembalikan. GET /session/ mengizinkan 30 permintaan per menit dan 300 per jam per alamat, batas yang juga dipakai bersama dengan DELETE /session/. Verifikasi token secara offline pada setiap permintaan, dan gunakan panggilan ini hanya pada saat diperlukan. Setiap panggilan yang berhasil dihitung sebagai aktivitas, sehingga memulai ulang idle_timeout sesi. Email yang terverifikasi bukan verifikasi identitas. Baca verified untuk hal itu: di sini nilainya null jika tidak ada, sementara token memuat {}.

Refresh token

Refresh mengembalikan token akses, ID token, dan refresh token baru, dan refresh token yang Anda kirim berhenti berfungsi.
  • Refresh token adalah string acak yang berlaku hingga sesi berakhir.
  • Penggunaan ulang mengakhiri sesi. Ketika refresh token yang sudah dipakai datang lagi, Didit menganggapnya sebagai tanda pencurian: sesi dicabut dan respons 400 {"error": "invalid_grant"} dikembalikan. Token sesi juga berhenti berfungsi, termasuk yang berasal dari refresh sebelumnya: refresh token-nya gagal, dan token akses-nya langsung gagal pada GET /session/, meskipun masih lolos verifikasi offline hingga kedaluwarsa dalam waktu 5 menit.
  • Jalankan hanya satu refresh secara bersamaan untuk sebuah sesi, di seluruh tab, perangkat, dan instans server, lalu ganti ketiga token sekaligus.
  • Jika refresh gagal dengan 400 atau tidak mendapat jawaban, mulai login lagi. Jangan mencoba ulang secara membabi buta: percobaan ulang setelah refresh yang sebenarnya berhasil merupakan penggunaan ulang.
  • 503 {"error": "temporarily_unavailable"} berarti refresh tidak terjadi dan refresh token Anda masih berfungsi. Coba lagi dengan backoff.
  • Didit menjawab 429 sebelum refresh dijalankan, jadi coba lagi setelah Retry-After. Endpoint token mengizinkan 30 permintaan per menit dan 300 per jam per alamat. Selain itu, setiap POST dan DELETE aplikasi Anda berbagi bucket proteksi bot: 60 permintaan per menit per alamat di seluruh endpoint tersebut, dan 30 per menit per perangkat. Untuk seluruh aplikasi, refresh memiliki bucket 6,000 per menit, dan setiap POST dan DELETE lainnya (termasuk permintaan dari browser dan langkah login) memiliki bucket 3,000 per menit, sehingga refresh tidak pernah menghabiskan kuota login Anda.
  • Dengan token akses 5 menit, 300 refresh per jam cukup untuk sekitar 25 orang yang tetap aktif. Jika server Anda melakukan refresh untuk banyak orang dari satu alamat, lakukan refresh hanya saat sebuah permintaan membutuhkan token baru, dan lakukan refresh di browser atau aplikasi bila memungkinkan.

Keluar

DELETE /session/ dengan access token pengguna saat ini mengakhiri sesi dan mengembalikan 204. Refresh token-nya berhenti berfungsi, dan access token-nya langsung gagal pada GET /session/. Token yang Anda verifikasi secara offline tetap berlaku hingga kedaluwarsa. Setelah itu, arahkan pengguna ke post_logout_redirect_uri Anda, jika Anda menetapkannya. Keluar memerlukan access token yang akan diterima oleh GET /session/: token yang belum kedaluwarsa dan belum diganti melalui refresh. Respons 401 berarti sesi belum berakhir. Lakukan refresh, lalu keluar dengan access token yang baru. Jika refresh gagal dengan 400, sesi tidak dapat digunakan lagi. Sesi juga berakhir apabila:
  • melewati session_lifetime (default 30 hari) atau idle_timeout (default 1 hari),
  • pengguna masuk kembali saat sesi multipel dinonaktifkan,
  • pengguna mengatur ulang kata sandinya saat revoke_on_password_change aktif,
  • tim Anda mencabut sesi atau memblokir pengguna di konsol,
  • refresh token yang sudah dipakai dikirim lagi.

Masa berlaku

Simpan kredensial sesuai tujuannya

  • Simpan kunci API verifikasi dan token konsol di server Anda.
  • Simpan access token browser di memori jika memungkinkan. Untuk aplikasi yang di-render di server, gunakan cookie HttpOnly yang aman dan lindungi permintaan yang diautentikasi dengan cookie dari CSRF.
  • Simpan refresh token aplikasi seluler di penyimpanan yang dilindungi platform. Hapus state lokal setelah keluar.
  • Jangan pernah menaruh token di URL atau log.
Lanjutkan dengan quickstart JavaScript, quickstart Next.js atau referensi API Autentikasi.
Terakhir diubah pada 7 November 2026