Integrasi aplikasi seluler
Caputchin berjalan di dalam aplikasi native lewat sebuah halaman sematan terhosting. Kamu mengarahkan sebuah WebView ke halaman itu, pengunjung menuntaskan tantangan di dalamnya, dan halaman menjembatani token hasilnya (dan galat apa pun) kembali ke kode native-mu. Verifikasinya sendiri identik dengan web; hanya shell host-nya yang berbeda.
1. Buka halaman sematan
Arahkan sebuah WebView ke https://caputchin.com/embed dengan setidaknya sebuah kunci situs:
https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memoryHilangkan parameter game untuk checkbox biasa. Sebuah daftar games=a,b memilih satu secara acak per sesi.
Parameter kueri
| Parameter | Wajib | Efek |
|---|---|---|
sitekey | ya | Public key-mu (cpt_pub_...). Jika hilang, merender shell galat tanpa widget. |
game | tidak | Sebuah id game marketplace tunggal (owner/repo, atau owner/repo/leaf). |
games | tidak | Sebuah daftar dipisah koma; satu dipilih acak per sesi. |
game-src | tidak | URL bundel game terhosting milikmu sendiri, untuk game swahosting. |
layout | tidak | inline, modal, fullscreen, atau auto. Default ke inline pada sematan. |
locale / skin / config | tidak | Diteruskan ke widget untuk memilih bahasa, skin, atau konfigurasi. |
no-verify | tidak | Menjalankan game tanpa gerbang verifikasi (game saja, tanpa token). |
postMessageTarget | tidak | Hanya penyemat iframe-peramban (lihat di bawah). Diabaikan di WebView native. |
Hilangkan ketiga game / games / game-src untuk checkbox biasa. Tak ada parameter mode; widget mengemudikan pemicunya sendiri.
2. Jembatani token ke kodemu
Saat pengunjung lolos, halaman sematan mendorong token lewat kanal yang cocok dengan host-mu. Daftarkan handler yang cocok.
iOS (WKWebView, Swift)
Token tiba sebagai string mentah pada sebuah message handler bernama caputchin:
class TokenHandler: NSObject, WKScriptMessageHandler {
func userContentController(_ controller: WKUserContentController,
didReceive message: WKScriptMessage) {
guard let token = message.body as? String else { return }
// send `token` to your backend
}
}
let config = WKWebViewConfiguration()
config.userContentController.add(TokenHandler(), name: "caputchin")
let webView = WKWebView(frame: .zero, configuration: config)
webView.load(URLRequest(url: URL(string: "https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memory")!))Android (WebView, Kotlin)
Token tiba sebagai string mentah pada sebuah @JavascriptInterface bernama caputchin:
class TokenBridge {
@JavascriptInterface
fun onToken(token: String) {
// send `token` to your backend
}
}
webView.settings.javaScriptEnabled = true
webView.addJavascriptInterface(TokenBridge(), "caputchin")
webView.loadUrl("https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memory")React Native (react-native-webview)
Sematan memposting sebuah string JSON pada kanal React Native tunggal. Urai dan cabangkan berdasarkan type:
<WebView
source={{ uri: "https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memory" }}
onMessage={(e) => {
const msg = JSON.parse(e.nativeEvent.data);
if (msg.type === "caputchin-token") {
// send msg.token to your backend
} else if (msg.type === "caputchin-error") {
// msg.code, msg.message, msg.originalCode (optional)
}
}}
/>Iframe peramban (postMessage)
Jika kamu menyematkan halaman di <iframe> peramban alih-alih WebView native, relai induk mati secara baku dan hanya menyala saat kamu memilih masuk dengan origin target yang persis lewat ?postMessageTarget=<origin> (misalnya postMessageTarget=https://app.example.com). Sebuah wildcard (*), sebuah path, atau apa pun yang tak terurai menjadi skema, host, dan port telanjang ditolak, jadi token sekali-pakai yang terikat-situs tak pernah disiarkan ke induk yang tak terverifikasi. Dengarkan di induk dan periksa event.origin sebelum memercayai pesan:
window.addEventListener("message", (event) => {
if (event.origin !== "https://embed-host.example.com") return;
const msg = event.data;
if (msg.type === "caputchin-token") {
// msg.token
} else if (msg.type === "caputchin-error") {
// msg.code, msg.message
}
});3. Verifikasi di backend-mu
Ini sama seperti web: POST token ke /siteverify dengan secret-mu. Lihat Integrasi sisi server.
Menerima galat (opsional)
Kapan pun widget menemui galat, halaman sematan mencerminkannya lewat satu set kanal paralel: message handler iOS caputchinError, interface Android caputchinError (onError(json)), kanal React Native sebagai { type: "caputchin-error", ... }, dan relai iframe bergerbang yang sama. Muatannya membawa { code, message, originalCode? }. iOS dan Android menerimanya sebagai string JSON; React Native dan relai iframe menerima amplop bertipe.
Ini sepenuhnya opsional. Sebuah aplikasi yang tak mendaftarkan handler galat sekadar tak menerima galat, dan halaman sematan toh sudah menampilkan UI coba-lagi di dalam WebView.
Lihat juga
- Integrasi sisi server untuk pemeriksaan token.
- Integrasi sisi klien untuk padanan web-nya.