Panduan OAuth

Flow app-to-app + PKCE

Pengguna memberi izin di dalam aplikasi Tracive, dan aplikasi Anda menerima token pendek yang terikat ke pengguna itu. Pengecekan ditagihkan ke kredit langganan pengguna — bukan ke Anda — dan aplikasi Anda tidak pernah menyimpan kredensial berumur panjang.

Tidak ada parameter API key di seluruh permukaan publik SDK, di mode apa pun. Kalau Anda mencari tempat menyimpan secret, yang Anda butuhkan adalah Proxy mode — dan itu Fase 2.

Dua panggilan, bukan satu

Consent terjadi di aplikasi Tracive, jadi aplikasi Anda ada di background selama itu dan boleh dimatikan OS. Panggilan yang menunggu redirect akan lenyap sebelum redirect-nya tiba — karena itu alurnya dipecah dua.

Android + iOS (KMP)
// 1. Otorisasi sekali. Membuka layar consent Tracive di Custom Tab, lalu selesai.
when (val start = client.oauth!!.authorize()) {
  null                       -> waitForTheRedirect()      // halaman sudah terbuka
  is AuthResult.AppNotInstalled -> tellUserToInstallTracive()  // store sudah dibuka
  is AuthResult.Failed       -> report(start.error)       // tidak ada yang dibuka
  else -> error("authorize() tidak mengembalikan apa pun selain itu")
}

// 2. Rutekan redirect kembali, dari onNewIntent / onOpenURL, di dalam coroutine.
//    Di sinilah otorisasi benar-benar berakhir — jangan buang hasilnya.
when (val auth = client.oauth!!.handleCallback(incomingUrl)) {
  null                        -> keepRoutingThisDeepLink()  // bukan redirect Tracive
  is AuthResult.Authorized    -> proceed(auth.grantedScopes)
  is AuthResult.CodeReceived  -> sendToOwnBackend(auth.code, auth.codeVerifier, auth.redirectUri)
  is AuthResult.Denied        -> respectThat()
  is AuthResult.Failed        -> report(auth.error)
  else -> Unit
}

Empat SDK, satu bentuk

Keempat SDK dibekukan terhadap kontrak lintas-bahasa yang sama: nama metode, bentuk hasil, dan penanganan error-nya sepadan. Kode di atas berbeda di sintaks, tidak di alur.

Cek aplikasi terpasang

Kalau aplikasi Tracive tidak ada, authorize() tidak membuka layar consent — ia membuka tautan install, tanpa membawa satu pun parameter OAuth. Tidak ada resume tertunda: pengguna kembali dan mencoba lagi.

PKCE S256 saja

Tidak ada cabang plain di mana pun — tidak di consent, tidak di penukaran. Permintaan tanpa code_challenge S256 ditolak, dan itu bukan sesuatu yang bisa dilonggarkan per client.

Custom Tab, bukan WebView

Consent dibuka di Custom Tab / SFSafariViewController, bukan WebView di dalam aplikasi Anda. Bedanya bukan gaya: WebView memberi aplikasi tuan rumah akses ke isi halaman, yang berarti kredensial Tracive pengguna melewati proses Anda.

Redirect URI: App Link

Dicocokkan exact-match, termasuk skema dan host. Custom scheme diizinkan (RFC 8252) tetapi ditandai di portal — di perangkat yang sama, aplikasi lain bisa mendaftarkan skema yang sama dan menangkap redirect Anda. App Link terverifikasi tidak bisa.

Public vs confidential

Public: SDK menukar code-nya sendiri, tanpa secret. Confidential: SDK mengembalikan codeReceived dan backend Anda yang menukarnya, karena di sanalah client secret boleh disimpan.