Cara Identifikasi Pengguna yang Login di Live Chat (dan Mencegah Penyamaran)
Mengirim ID pengguna begitu saja ke widget chat membuat siapa pun bisa mengubahnya di DevTools dan chat sebagai pelanggan terbaik Anda. Ini versi yang ditandatangani, dengan kode Node dan PHP.
Untuk mengidentifikasi pengguna yang login di live chat, aktifkan verifikasi identitas pengunjung, tanda tangani ID setiap pengguna di server Anda dengan HMAC-SHA256, lalu kirim ID beserta signature-nya ke widget chat. Agen pun melihat pelanggan terverifikasi lengkap dengan namanya di perangkat mana pun, sementara siapa pun yang mengubah ID di browser diperlakukan sebagai pengunjung anonim.
Ringkasan
- ID pengguna polos di halaman bisa diubah lewat DevTools, sehingga siapa pun bisa menyamar sebagai pelanggan Anda.
- SealReply memeriksa signature HMAC-SHA256 dari ID pengguna, yang dibuat di server Anda dengan rahasia berawalan
ids_. - Tanda tangani ID yang tidak pernah berubah, seperti primary key, jangan alamat email.
- Signature yang hilang atau salah tidak pernah merusak chat: pengunjung hanya tetap anonim, jadi uji dengan akun sungguhan setelah rilis.
- Fitur ini tersedia di semua paket; hanya pemilik ruang kerja dan admin yang bisa membuat rahasianya.
Langkah tengah itulah intinya: signature harus dibuat di server Anda. Di bawah ini: kenapa ID pengguna polos tidak cukup, tiga langkah pemasangan dengan kode Node dan PHP, apa yang benar-benar dilihat agen, dan daftar singkat penyebab setup yang tampak benar tapi diam-diam tidak berfungsi.

Apa masalahnya jika hanya mengirim ID pengguna?
ID pengguna polos membuat siapa pun bisa berpura-pura menjadi siapa saja. Misalkan aplikasi Anda punya sistem akun, dan Anda ingin agen tahu sedang berbicara dengan pelanggan yang mana. Versi yang menggoda untuk dipakai:
<!-- Don't do this -->
<script>
window.chatUser = { id: "10231", name: "Dana Ellis", plan: "Enterprise" };
</script>
Apa pun yang ada di halaman bisa diubah oleh orang yang sedang melihatnya. Buka DevTools, ganti 10231 dengan nomor akun orang lain, ubah plan menjadi Enterprise, lalu reload. Apa yang dilihat agen Anda sekarang adalah apa pun yang diketik pengunjung. Ada dua masalah nyata yang muncul:
Penyamaran. Seseorang membuka chat sebagai salah satu pelanggan Anda dan bertanya hal yang biasanya dijawab agen tanpa berpikir panjang: "bisa ingatkan alamat pengiriman pesanan terakhir saya?", "tolong ganti nomor telepon di akun saya". Agen melihat pelanggan yang sudah login, jadi mereka menjawab. ID akun jarang benar-benar rahasia; ID muncul di invoice, halaman pesanan, dan screenshot dukungan.
Membaca riwayat chat orang lain. Salah satu manfaat mengidentifikasi pengguna adalah mereka bisa membuka kembali percakapan sebelumnya. Jika identitas hanya berupa ID polos di halaman, ID itu menjadi kunci ke riwayat chat orang lain.
Para ahli keamanan menyebut pola ini insecure direct object reference: aplikasi memercayai identifier yang dikendalikan pengunjung, alih-alih memeriksa apakah pengunjung boleh memakainya (cheat sheet OWASP membahas versi umumnya).
Signature memperbaiki tepat masalah ini. ID tetap publik dan bisa dibaca; hanya server Anda yang bisa membuat string pasangannya. Ubah ID-nya, dan pasangan itu tidak lagi cocok.
Bagaimana cara kerja identifikasi pengguna yang login?
Verifikasi identitas pengunjung adalah pengaturan situs di SealReply yang membuat widget hanya memercayai ID pengguna jika datang bersama signature buatan server Anda sendiri. Ada tiga bagian yang terlibat:
- Rahasia. String acak yang hanya diketahui server Anda dan SealReply. Anda membuatnya di pengaturan situs, dan rahasia ini disimpan terenkripsi.
- Server Anda. Server sudah tahu siapa yang sedang login, jadi server menandatangani ID pengguna itu dengan rahasia tadi.
- Widget. Widget membawa ID dan signature. SealReply menghitung ulang signature dengan rahasia yang sama lalu membandingkannya. Cocok, pengunjung terverifikasi; tidak cocok, mereka hanya pengunjung anonim.

Algoritmanya HMAC-SHA256, yaitu keyed hash yang didefinisikan di RFC 2104: rahasia yang sama dan teks yang sama selalu menghasilkan output 64 karakter yang sama, dan tanpa rahasia itu tidak ada yang bisa membuat hasil yang cocok. Ini primitif yang sama dengan yang Anda pakai untuk webhook masuk, hanya arahnya terbalik: saat verifikasi signature webhook Anda memeriksa signature buatan pihak lain, sedangkan di sini Anda membuat signature untuk pengguna Anda sendiri.
Langkah 1: Aktifkan dan salin rahasianya
Rahasia didapat dari pengaturan situs dan hanya ditampilkan satu kali. Di konsol, buka Situs, pilih situs web Anda, lalu cari bagian Identitas (kartunya berjudul Verifikasi identitas pengunjung):
- Klik Aktifkan.
- Salin rahasianya (berawalan
ids_). Rahasia hanya ditampilkan sekali dan tidak akan muncul lagi. - Perlakukan seperti password: simpan di environment variable server, jangan di repo, jangan di file apa pun yang diunduh browser.
Siapa yang bisa mengaktifkan
Verifikasi identitas pengunjung tersedia di semua paket, termasuk Gratis. Hanya pemilik ruang kerja dan admin yang melihat tombol Aktifkan dan Buat rahasia baru; agen tidak.
Jika widget belum terpasang di situs Anda, mulai dari cara memasang live chat di situs web.
Contoh di bawah mengasumsikan rahasia disimpan di SEALREPLY_IDENTITY_SECRET.
Langkah 2: Tanda tangani ID pengguna di server
Server Anda menandatangani ID pengguna, dan tidak ada yang lain. Yang ditandatangani adalah ID pengguna di sistem Anda sendiri. Hasilnya berupa hex:
// Node.js
import { createHmac } from "node:crypto";
const identityHash = createHmac("sha256", process.env.SEALREPLY_IDENTITY_SECRET)
.update(String(user.id))
.digest("hex");
<?php
// PHP
$identityHash = hash_hmac('sha256', (string) $user->id, getenv('SEALREPLY_IDENTITY_SECRET'));
Versi Python dan Go ada di dokumentasi widget dan bekerja persis sama: rahasia yang sama dan ID pengguna yang sama menghasilkan string hex 64 karakter yang sama di bahasa mana pun.
Jangan pernah menandatangani di browser
Jika identity_hash dihitung di JavaScript frontend, rahasianya harus ada di JavaScript itu, dan siapa pun bisa membacanya lalu menandatangani ID apa saja. Hitung di backend dan cetak hanya hasilnya ke halaman.
ID mana yang sebaiknya ditandatangani? Sesuatu yang tidak berubah di database Anda: primary key atau UUID, bukan alamat email atau nomor telepon. Saat pelanggan mengganti email, signature atas email itu ikut berubah, SealReply menganggapnya orang yang berbeda, dan riwayatnya tidak lagi mengikuti dia.
ID boleh sampai 128 karakter dan dibandingkan persis seperti yang Anda tanda tangani, tanpa trim dan tanpa penyamaan huruf besar-kecil. Tanda tangani dan kirim string yang identik: "42" dan " 42" adalah dua orang berbeda.
Langkah 3: Kirim ke widget
Widget butuh ID dan signature sebelum mulai berjalan. Di halaman tempat pengguna sudah login, atur identitas sebelum widget.js dimuat:
<script>
window.sealreplySettings = {
identity: {
external_id: "10231", // the user's ID in your app
identity_hash: "<from your server>",
name: "Dana Ellis", // optional, shown to agents
email: "dana@example.com", // optional
},
};
</script>
<script src="https://cdn.sealreply.com/widget.js" data-site-key="sk_…" async></script>
Kedua nilai berasal dari template sisi server Anda, entah Blade, ERB, template Django, React server component, atau apa pun yang Anda pakai. Jangan pernah menghitungnya di browser.
Di single-page app tidak ada pemuatan halaman penuh, jadi panggil ini begitu pengguna login:
SealReply.identify({
external_id: "10231",
identity_hash: "<from your server>",
name: "Dana Ellis",
email: "dana@example.com",
});
Widget dimuat ulang sebagai pengguna tersebut. Saat logout, panggil:
SealReply.reset();
Jangan lewatkan reset(). Setelah pengguna logout, ID anonim browser tidak lagi bisa membuka percakapannya; hanya signature yang valid yang bisa. Tetapi tanpa reset(), chat yang dimulai secara anonim sesudahnya di komputer bersama akan tertempel ke orang berikutnya yang login di sana.
Apa yang dilihat agen setelah pengguna teridentifikasi?
Agen melihat pelanggan bernama dengan tanda Terverifikasi dan satu riwayat di semua perangkat. Di panel Pengunjung di samping percakapan:
- Pengunjung diberi tanda Terverifikasi, dengan ID akun yang Anda tanda tangani di bawahnya. Tidak ada lagi agen yang harus membuka chat dengan "ini untuk akun yang mana ya?".
- Ponsel, laptop, komputer kantor: ID sama, pengunjung sama, satu riwayat yang bersambung.
- Pengunjung terverifikasi bisa membuka kembali chat sebelumnya dari menu widget di perangkat mana pun. Yang ditampilkan hanya percakapan yang dimulai setelah mereka pertama kali login, jadi apa pun yang dilakukan orang lain secara anonim di komputer bersama sebelumnya tidak ikut muncul.
- Jika Anda memakai formulir pra-chat, pengunjung terverifikasi tidak ditanya nama dan email lagi.
Karena signature-lah yang membuka riwayat itu, perlakukan identity_hash seperti password juga: jangan di URL, jangan di halaman yang bisa dilihat orang lain. Apa yang terjadi pada pesan itu sendiri dibahas di apakah live chat Anda privat.
Field mana yang terverifikasi, dan mana yang tidak?
Hanya external_id yang ditandatangani. name dan email tidak: keduanya hanya mengisi detail pengunjung yang masih kosong, tidak pernah menimpa apa yang sudah diketik agen, dan sebaiknya Anda baca sebagai "yang diklaim halaman".
| Field | Ditandatangani? | Fungsinya |
|---|---|---|
external_id |
Ya, oleh identity_hash |
Mengikat pengunjung ke satu orang di semua perangkat dan membuka riwayat chat mereka |
name, email |
Tidak | Mengisi detail pengunjung yang kosong; tidak pernah menimpa isian agen |
attributes |
Ya, oleh attributes_hash |
Mengganti detail member yang ditampilkan ke agen (paket, pesanan, total belanja) |

Signature yang hilang, salah, atau verifikasi yang dimatikan tidak memunculkan error dan tidak menyembunyikan widget. Pengunjung hanya menjadi anonim dan chat berjalan seperti biasa. Ini disengaja: template yang rusak seharusnya hanya membuat Anda kehilangan nama di sidebar, bukan kehilangan chat di situs web Anda.
Uji seperti pelanggan
Tidak ada yang memberi tahu Anda saat verifikasi gagal. Setelah rilis, login ke situs Anda dengan akun sungguhan, buka chat, kirim pesan, lalu pastikan panel Pengunjung di konsol menampilkan Terverifikasi.
Bisakah mengirim paket, jumlah pesanan, dan total belanja juga?
Bisa: rahasia yang sama juga menandatangani detail member. Mekanisme yang sama membawa detail member, seperti paket, jumlah pesanan, dan lifetime value, ke panel Pengunjung, sehingga agen tidak perlu pindah tab untuk mencarinya. Detail ini juga ditandatangani, karena tanpa itu pengunjung bisa "menaikkan" dirinya sendiri ke Enterprise lewat console browser.
Pesan yang ditandatangani adalah ID pengguna, lalu satu baris key=value per atribut diurutkan berdasarkan key, digabung dengan baris baru. Untuk pengguna 42 dengan plan=Gold dan orders=12, Anda menandatangani tiga baris ini:
42
orders=12
plan=Gold
// Node.js
const attributes = { plan: "Gold", orders: "12" };
const message = [String(user.id), ...Object.keys(attributes).sort().map((k) => `${k}=${attributes[k]}`)].join("\n");
const attributesHash = createHmac("sha256", process.env.SEALREPLY_IDENTITY_SECRET).update(message).digest("hex");
<?php
// PHP
$attributes = ['plan' => 'Gold', 'orders' => '12'];
ksort($attributes, SORT_STRING);
$lines = [(string) $user->id];
foreach ($attributes as $k => $v) { $lines[] = "$k=$v"; }
$attributesHash = hash_hmac('sha256', implode("\n", $lines), getenv('SEALREPLY_IDENTITY_SECRET'));
Kirim bersama identitasnya:
window.sealreplySettings = {
identity: {
external_id: "42",
identity_hash: "<signature of the user ID>",
attributes: { plan: "Gold", orders: "12" },
attributes_hash: "<signature of the attributes>",
},
};
Batasannya: maksimal 30 atribut, key maksimal 40 karakter, value maksimal 200, tanpa baris baru, dan tanpa = di key. Gunakan hanya huruf ASCII, angka, dan garis bawah untuk key, seperti total_spent, supaya pengurutan default di bahasa mana pun menghasilkan urutan yang sama; urutan yang tidak cocok adalah kesalahan paling umum di sini. Value boleh berisi teks apa saja.
Dengan signature yang valid, atribut mengganti seluruh detail member pengunjung; dengan signature yang salah, seluruh set diabaikan dan identifikasi tetap berjalan seperti biasa.
Bagaimana menjaga rahasia identitas?
Simpan di server dan ganti segera begitu ada kemungkinan bocor; OWASP Secrets Management Cheat Sheet adalah referensi umum yang bagus.
- Hanya di sisi server: environment variable atau secret manager. Jangan di repo, jangan di bundle frontend, jangan di aplikasi mobile.
- Signature tidak pernah kedaluwarsa. Jika ada yang mungkin bocor, satu-satunya solusi adalah Buat rahasia baru di pengaturan situs, yang mematikan rahasia lama.
Urutan mengganti rahasia
Buat rahasia baru langsung berlaku. Pasang rahasia baru di server Anda terlebih dulu (deploy, restart), baru klik tombol itu di konsol. Jika urutannya terbalik, semua pengguna yang login kembali menjadi anonim sampai server Anda menyusul.
- Matikan membuat semua orang kembali anonim; identitas yang sudah tercatat tidak dihapus.
Kenapa pengunjung masih tampil anonim?
Hampir selalu karena salah satu dari enam hal ini, dan widget tidak akan memberi tahu yang mana. Periksa tabel ini dari atas ke bawah:
| Yang Anda lihat | Kemungkinan penyebab | Solusi |
|---|---|---|
| Tidak ada yang pernah terverifikasi | Verifikasi belum aktif | Bagian Identitas di pengaturan situs harus menunjukkan Aktif |
| Tidak ada yang pernah terverifikasi | Anda menandatangani string yang berbeda dari external_id |
Tanda tangani persis string itu: bukan email, bukan "user:42", tanpa spasi berlebih; ubah ID numerik menjadi string |
| Semua jadi anonim setelah deploy | Rahasia di server lama atau terpotong | Salin lengkap (ids_ ditambah 64 karakter hex, total 68), perbarui variabelnya, restart layanan |
| Berhasil saat tes, tidak untuk pengguna sungguhan | identity_hash dihitung di browser |
Rahasianya sudah publik: buat rahasia baru dan pindahkan penandatanganan ke server |
| Baru berhasil setelah halaman di-reload | window.sealreplySettings diatur setelah widget.js |
Taruh pengaturan sebelum tag, atau panggil SealReply.identify() |
| Satu pengguna melihat nama pengguna lain | Cache CDN halaman penuh menyajikan signature milik orang lain | Jangan cache halaman penuh yang membawa identitas |
Pertanyaan umum
Apakah identity_hash rahasia seperti password?
Ya, perlakukan seperti password. Siapa pun yang memegang ID pengguna beserta identity_hash-nya bisa membuka chat lama pengguna itu dari widget, dan signature tidak pernah kedaluwarsa. Jangan pernah menaruhnya di URL, baris log, atau halaman yang bisa dilihat orang lain.
Bolehkah menandatangani alamat email pengguna, bukan ID?
Boleh, tetapi sebaiknya jangan. Signature atas email berubah saat pelanggan mengganti emailnya, lalu SealReply melihat orang baru yang riwayatnya tidak ikut. Tanda tangani primary key atau UUID, dan kirim email secara terpisah di email.
Apa yang terjadi jika signature salah atau tidak ada?
Pengunjung chat sebagai pengunjung anonim, persis seperti saat verifikasi dimatikan. Widget tidak menampilkan error dan tetap berjalan, dan ini disengaja: template yang rusak seharusnya hanya membuat Anda kehilangan nama di sidebar, bukan chat-nya. Hal yang sama berlaku untuk attributes_hash yang salah: detail member diabaikan dan identifikasi tetap berjalan.
Apakah verifikasi identitas pengunjung berfungsi di aplikasi mobile?
Ya, melalui tautan chat halaman penuh yang Anda buka dari tombol "Hubungi kami" di aplikasi. Tambahkan external_id, identity_hash, name, dan email setelah tanda # di tautan itu, ditandatangani di server Anda persis seperti untuk situs web. Halaman chat aplikasi membutuhkan domain terverifikasi terlebih dulu, dan rahasianya tidak boleh dimasukkan ke dalam aplikasi.
Apakah perlu paket berbayar untuk mengidentifikasi pengguna yang login?
Tidak. Verifikasi identitas pengunjung tersedia di semua paket, termasuk Gratis. Hanya pemilik ruang kerja dan admin yang bisa mengaktifkannya atau membuat rahasia baru.
Bagaimana cara mengeluarkan pengguna dari chat saat logout?
Panggil SealReply.reset() saat pengguna logout dari situs Anda. Percakapan mereka memang sudah tidak bisa dibuka tanpa signature yang valid, tetapi reset() juga memulai pengunjung anonim yang baru, sehingga chat yang dimulai sesudahnya di komputer bersama tidak diserahkan ke orang berikutnya yang login.
Langkah selanjutnya
Dengan verifikasi identitas aktif, agen tidak lagi membuka percakapan dengan "Pengunjung 2"; mereka melihat nama, paket, dan semua yang pernah ditanyakan orang itu. Padukan dengan status prospek dan pengingat tindak lanjut agar chat yang bagus tidak berhenti di ucapan perpisahan. external_id yang sudah ditandatangani juga yang memungkinkan Anda mengirim balik data pesanan dan melihat chat mana yang berujung pembelian — lihat cara tracking konversi live chat di Google Analytics 4. Untuk pengaturan lain yang layak dilakukan sejak awal, lihat mulai menggunakan SealReply.