pengantar
Saya tidak tahu apakah ada atau pernah ada cara untuk mengidentifikasi mesin secara unik menggunakan browser saja. Alasan utamanya adalah:
- Anda harus menyimpan data di komputer pengguna. Data ini dapat dihapus oleh pengguna kapan saja. Kecuali jika Anda memiliki cara untuk membuat kembali data ini yang unik untuk setiap mesin maka perangkat Anda macet.
- Validasi. Anda harus menjaga dari spoofing, pembajakan sesi, dll.
Bahkan jika ada cara untuk melacak komputer tanpa menggunakan cookie, selalu ada cara untuk mem-bypassnya dan perangkat lunak yang akan melakukan ini secara otomatis. Jika Anda benar-benar perlu melacak sesuatu berdasarkan komputer Anda harus menulis aplikasi asli (Apple Store / Android Store / Program Windows / dll).
Saya mungkin tidak dapat memberi Anda jawaban untuk pertanyaan yang Anda ajukan tetapi saya dapat menunjukkan kepada Anda bagaimana menerapkan pelacakan sesi. Dengan pelacakan sesi, Anda mencoba melacak sesi penelusuran alih-alih komputer mengunjungi situs Anda. Dengan melacak sesi, skema basis data Anda akan terlihat seperti ini:
sesssion:
sessionID: string
// Global session data goes here
computers: [{
BrowserID: string
ComputerID: string
FingerprintID: string
userID: string
authToken: string
ipAddresses: ["203.525....", "203.525...", ...]
// Computer session data goes here
}, ...]
Keuntungan dari pelacakan berbasis sesi:
- Untuk pengguna yang masuk, Anda selalu dapat membuat id sesi yang sama dari pengguna
username
/ password
/ email
.
- Anda masih dapat melacak pengguna tamu menggunakan
sessionID
.
- Bahkan jika beberapa orang menggunakan komputer yang sama (yaitu cybercafe), Anda dapat melacaknya secara terpisah jika mereka masuk.
Kerugian dari pelacakan berbasis sesi:
- Sesi berdasarkan browser dan bukan berbasis komputer. Jika pengguna menggunakan 2 browser yang berbeda, itu akan menghasilkan 2 sesi yang berbeda. Jika ini masalah Anda bisa berhenti membaca di sini.
- Sesi kedaluwarsa jika pengguna tidak masuk. Jika pengguna tidak masuk, maka mereka akan menggunakan sesi tamu yang akan dibatalkan jika pengguna menghapus cookie dan cache browser.
Penerapan
Ada banyak cara untuk mengimplementasikan ini. Saya tidak berpikir saya bisa membahas semuanya, saya hanya akan daftar favorit saya yang akan membuat ini menjadi pendapat yang beralasan . Ingatlah itu.
Dasar-dasar
Saya akan melacak sesi dengan menggunakan apa yang dikenal sebagai cookie selamanya. Ini adalah data yang secara otomatis akan membuat ulang dirinya sendiri bahkan jika pengguna menghapus cookie atau memperbarui browser-nya. Namun itu tidak akan bertahan hidup pengguna menghapus cookie dan cache browsing mereka.
Untuk mengimplementasikan ini saya akan menggunakan mekanisme caching browser ( RFC ), WebStorage API ( MDN ) dan cookie browser ( RFC , Google Analytics ).
Hukum
Untuk memanfaatkan id pelacakan, Anda harus menambahkannya ke kebijakan privasi Anda dan ketentuan penggunaan Anda lebih disukai di bawah Sub-heading Tracking . Kami akan menggunakan kunci berikut pada keduanya document.cookie
dan window.localStorage
:
- _ga : data Google Analytics
- __utma : cookie pelacakan Google Analytics
- sid : SessionID
Pastikan Anda menyertakan tautan ke kebijakan Privasi Anda dan ketentuan penggunaan pada semua halaman yang menggunakan pelacakan.
Di mana saya menyimpan data sesi saya?
Anda dapat menyimpan data sesi di basis data situs web atau di komputer pengguna. Karena saya biasanya bekerja di situs yang lebih kecil (biarkan lebih dari 10 ribu koneksi terus menerus) yang menggunakan aplikasi pihak ke-3 (Google Analytics / Clicky / dll) yang terbaik bagi saya untuk menyimpan data di komputer klien. Ini memiliki keuntungan sebagai berikut:
- Tidak ada pencarian basis data / overhead / beban / latensi / ruang / dll.
- Pengguna dapat menghapus data mereka kapan pun mereka mau tanpa perlu menulis email yang mengganggu saya.
dan kerugian:
- Data harus dienkripsi / didekripsi dan ditandatangani / diverifikasi yang menciptakan overhead CPU pada klien (tidak terlalu buruk) dan server (bah!).
- Data dihapus ketika pengguna menghapus cookie dan cache mereka. (Inilah yang benar-benar saya inginkan)
- Data tidak tersedia untuk analitik saat pengguna offline. (analytics hanya untuk pengguna yang sedang menjelajah)
UUIDS
- BrowserID : Id unik yang dihasilkan dari string agen pengguna browser.
Browser|BrowserVersion|OS|OSVersion|Processor|MozzilaMajorVersion|GeckoMajorVersion
- ComputerID : Dihasilkan dari Alamat IP pengguna dan kunci sesi HTTPS.
getISP(requestIP)|getHTTPSClientKey()
- FingerPrintID : JavaScript sidik jari berdasarkan berdasarkan dimodifikasi fingerprint.js .
FingerPrint.get()
- SessionID : Kunci acak yang dihasilkan ketika pengguna ke-1 mengunjungi situs.
BrowserID|ComputerID|randombytes(256)
- GoogleID : Dihasilkan dari
__utma
cookie.getCookie(__utma).uniqueid
Mekanisme
Suatu hari saya menonton acara williams wendy dengan pacar saya dan benar-benar ngeri ketika pembawa acara menyarankan pemirsa untuk menghapus riwayat browser mereka setidaknya sebulan sekali. Menghapus riwayat browser biasanya memiliki efek sebagai berikut:
- Menghapus riwayat situs web yang dikunjungi.
- Menghapus cookie dan
window.localStorage
(aww man).
Sebagian besar browser modern membuat opsi ini tersedia tetapi takut bukan teman. Karena ada solusinya. Peramban memiliki mekanisme caching untuk menyimpan skrip / gambar dan hal lainnya. Biasanya bahkan jika kita menghapus riwayat kita, cache browser ini masih ada. Yang kita butuhkan adalah cara untuk menyimpan data kita di sini. Ada 2 metode untuk melakukan ini. Yang lebih baik adalah menggunakan gambar SVG dan menyimpan data kami di dalam tag-nya. Dengan cara ini data masih dapat diekstraksi bahkan jika JavaScript dinonaktifkan menggunakan flash. Namun karena itu agak rumit saya akan menunjukkan pendekatan lain yang menggunakan JSONP ( Wikipedia )
example.com/assets/js/tracking.js (sebenarnya tracking.php)
var now = new Date();
var window.__sid = "SessionID"; // Server generated
setCookie("sid", window.__sid, now.setFullYear(now.getFullYear() + 1, now.getMonth(), now.getDate() - 1));
if( "localStorage" in window ) {
window.localStorage.setItem("sid", window.__sid);
}
Sekarang kita bisa mendapatkan kunci sesi kami kapan saja:
window.__sid || window.localStorage.getItem("sid") || getCookie("sid") || ""
Bagaimana cara membuat tracking.js menempel di browser?
Kita dapat mencapai ini menggunakan header HTTP Cache-Control , Last-Modified, dan ETag . Kita dapat menggunakan nilai SessionID
as untuk header etag:
setHeaders({
"ETag": SessionID,
"Last-Modified": new Date(0).toUTCString(),
"Cache-Control": "private, max-age=31536000, s-max-age=31536000, must-revalidate"
})
Last-Modified
header memberitahu browser bahwa file ini pada dasarnya tidak pernah dimodifikasi. Cache-Control
memberi tahu proksi dan gateway untuk tidak men-cache dokumen tetapi memberitahu browser untuk menyimpannya selama 1 tahun.
Saat berikutnya browser meminta dokumen, itu akan mengirim If-Modified-Since
dan If-None-Match
header. Kita dapat menggunakan ini untuk mengembalikan 304 Not Modified
respons.
example.com/assets/js/tracking.php
$sid = getHeader("If-None-Match") ?: getHeader("if-none-match") ?: getHeader("IF-NONE-MATCH") ?: "";
$ifModifiedSince = hasHeader("If-Modified-Since") ?: hasHeader("if-modified-since") ?: hasHeader("IF-MODIFIED-SINCE");
if( validateSession($sid) ) {
if( sessionExists($sid) ) {
continueSession($sid);
send304();
} else {
startSession($sid);
send304();
}
} else if( $ifModifiedSince ) {
send304();
} else {
startSession();
send200();
}
Sekarang setiap kali browser meminta tracking.js
server kami akan merespons dengan 304 Not Modified
hasil dan memaksakan eksekusi salinan lokal tracking.js
.
Saya masih tidak mengerti. Jelaskan itu padaku
Mari kita anggap pengguna menghapus riwayat penjelajahan mereka dan menyegarkan halaman. Satu-satunya yang tersisa di komputer pengguna adalah salinan dari tracking.js
cache browser. Ketika browser meminta, tracking.js
ia menerima 304 Not Modified
respons yang menyebabkannya menjalankan versi pertama yang tracking.js
diterima. tracking.js
mengeksekusi dan mengembalikan SessionID
yang telah dihapus.
Validasi
Misalkan Haxor X mencuri cookie pelanggan kami saat mereka masih login. Bagaimana kita melindungi mereka? Kriptografi dan sidik jari Browser untuk menyelamatkan. Ingat definisi asli kami SessionID
adalah:
BrowserID|ComputerID|randomBytes(256)
Kami dapat mengubah ini menjadi:
Timestamp|BrowserID|ComputerID|encrypt(randomBytes(256), hk)|sign(Timestamp|BrowserID|ComputerID|randomBytes(256), hk)
Mana hk = sign(Timestamp|BrowserID|ComputerID, serverKey)
.
Sekarang kita dapat memvalidasi SessionID
menggunakan algoritma berikut:
if( getTimestamp($sid) is older than 1 year ) return false;
if( getBrowserID($sid) !== createBrowserID($_Request, $_Server) ) return false;
if( getComputerID($sid) !== createComputerID($_Request, $_Server) return false;
$hk = sign(getTimestamp($sid) + getBrowserID($sid) + getComputerID($sid), $SERVER["key"]);
if( !verify(getTimestamp($sid) + getBrowserID($sid) + getComputerID($sid) + decrypt(getRandomBytes($sid), hk), getSignature($sid), $hk) ) return false;
return true;
Agar serangan Haxor berhasil, mereka harus:
- Sudah sama
ComputerID
. Itu berarti mereka harus memiliki penyedia ISP yang sama dengan korban (Tricky). Ini akan memberi korban kita peluang untuk mengambil tindakan hukum di negara mereka sendiri. Haxor juga harus mendapatkan kunci sesi HTTPS dari korban (Keras).
- Sudah sama
BrowserID
. Siapa pun dapat menipu string User-Agent (Annoying).
- Mampu membuat palsu mereka sendiri
SessionID
(Sangat Keras). Serangan volume tidak akan berhasil karena kami menggunakan cap waktu untuk menghasilkan kunci enkripsi / penandatanganan, jadi pada dasarnya seperti menghasilkan kunci baru untuk setiap sesi. Selain itu kami mengenkripsi byte acak sehingga serangan kamus sederhana juga keluar dari pertanyaan.
Kami dapat meningkatkan validasi dengan meneruskan GoogleID
dan FingerprintID
(melalui ajax atau bidang tersembunyi) dan mencocokkannya.
if( GoogleID != getStoredGoodleID($sid) ) return false;
if( byte_difference(FingerPrintID, getStoredFingerprint($sid) > 10%) return false;