Giriş
Tek başına bir tarayıcı kullanarak makineleri benzersiz bir şekilde tanımlamanın bir yolu olup olmayacağını bilmiyorum. Ana nedenler:
- Verileri kullanıcıların bilgisayarına kaydetmeniz gerekir. Bu veriler kullanıcı tarafından her zaman silinebilir. Her bir makine için benzersiz olan bu verileri yeniden oluşturmanın bir yolu yoksa, sıkışıp kalmazsınız.
- Doğrulama. Kimlik sahtekarlığına, oturum ele geçirmeye vb. Karşı korunmanız gerekir.
Bir bilgisayarı çerez kullanmadan izlemenin yolları olsa bile, her zaman onu ve bunu otomatik olarak yapacak yazılımı atlamanın bir yolu olacaktır. Bilgisayara dayalı bir şeyi gerçekten izlemeniz gerekiyorsa, yerel bir uygulama (Apple Store / Android Store / Windows Programı / vb.) Yazmanız gerekir.
Sorduğunuz soruya cevap veremeyebilirim, ancak oturum izlemeyi nasıl uygulayacağınızı gösterebilirim. Oturum izleme ile sitenizi ziyaret eden bilgisayar yerine tarama oturumunu izlemeye çalışırsınız. Oturumu izleyerek, veritabanı şemanız şöyle görünür:
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
}, ...]
Oturum tabanlı izlemenin avantajları:
- Giriş yapmış kullanıcılar için her zaman
username
/ password
/ kullanıcılarından aynı oturum kimliğini oluşturabilirsiniz email
.
- Düğmesini kullanarak konuk kullanıcıları yine de izleyebilirsiniz
sessionID
.
- Birkaç kişi aynı bilgisayarı kullansa bile (örneğin, cybercafe) oturum açmışlarsa ayrı ayrı izleyebilirsiniz.
Oturum tabanlı izlemenin dezavantajları:
- Oturumlar tarayıcı tabanlıdır, bilgisayar tabanlıdır. Bir kullanıcı 2 farklı tarayıcı kullanıyorsa, 2 farklı oturumla sonuçlanır. Bu bir sorunsa, burada okumayı bırakabilirsiniz.
- Kullanıcı oturum açmadıysa oturumların süresi dolar. Bir kullanıcı oturum açmadıysa, kullanıcı çerezleri ve tarayıcı önbelleğini silerse geçersiz kılınacak bir konuk oturumu kullanır.
uygulama
Bunu uygulamanın birçok yolu vardır. Bunları kapsayabileceğimi sanmıyorum, sadece favorimi listeleyeceğim, bu da tartışmalı bir cevap verecek . Bunu aklınızda tutun.
temeller
Sonsuza kadar çerez olarak bilinen şeyi kullanarak oturumu izleyeceğim. Bu, kullanıcı çerezlerini silse veya tarayıcısını güncellese bile kendisini otomatik olarak yeniden oluşturacak verilerdir. Ancak kullanıcının hem çerezlerini hem de tarama önbelleklerini silmesinden kurtulamaz.
Bunu uygulamak için tarayıcıların önbellekleme mekanizmasını ( RFC ), WebStorage API'sını ( MDN ) ve tarayıcı çerezlerini ( RFC , Google Analytics ) kullanacağım .
Yasal
İzleme kimliklerini kullanmak için bunları hem gizlilik politikanıza hem de kullanım şartlarınıza tercihen İzleme alt başlığı altında eklemeniz gerekir . İkimiz de aşağıdaki tuşları kullanır document.cookie
ve window.localStorage
:
- _ga : Google Analytics verileri
- __utma : Google Analytics izleme çerezi
- sid : Oturum Kimliği
İzleme kullanan tüm sayfalara Gizlilik politikanıza ve kullanım şartlarına bağlantılar eklediğinizden emin olun.
Oturum verilerimi nerede saklarım?
Oturum verilerinizi web sitenizin veritabanında veya kullanıcıların bilgisayarında depolayabilirsiniz. Normalde üçüncü taraf uygulamaları (Google Analytics / Clicky / vb.) Kullanan daha küçük sitelerde (10 bin kesintisiz bağlantıya izin vermeden) çalıştığımdan, verileri istemci bilgisayarında depolamak benim için en iyisidir. Bunun aşağıdaki avantajları vardır:
- Veritabanı araması / ek yük / yük / gecikme / boşluk / vb. Yok.
- Kullanıcı bana can sıkıcı e-postalar yazmak zorunda kalmadan verilerini istediği zaman silebilir.
ve dezavantajları:
- Verilerin şifrelenmesi / şifresinin çözülmesi ve imzalanması / doğrulanması gerekir; bu da istemcide (o kadar da kötü değil) ve sunucuda (bah!) İşlemci yükü oluşturur.
- Kullanıcı çerezlerini ve önbelleklerini sildiğinde veriler silinir. (bu gerçekten istediğim şey)
- Kullanıcılar çevrimdışına çıktığında veriler analitik için kullanılamaz. (yalnızca şu anda gezinen kullanıcılar için analiz)
UUIDs
- BrowserId : tarayıcılar kullanıcı aracısı dizesi üretilen benzersiz kimlik.
Browser|BrowserVersion|OS|OSVersion|Processor|MozzilaMajorVersion|GeckoMajorVersion
- ComputerID : Kullanıcıların IP Adresi ve HTTPS oturum anahtarından oluşturulur.
getISP(requestIP)|getHTTPSClientKey()
- FingerPrintID : Değiştirilmiş bir fingerprint.js tabanlı JavaScript tabanlı parmak izi .
FingerPrint.get()
- Oturum Kimliği : Kullanıcı 1. siteyi ziyaret ettiğinde rastgele anahtar oluşturulur.
BrowserID|ComputerID|randombytes(256)
- GoogleID : Çerezden oluşturulur
__utma
.getCookie(__utma).uniqueid
mekanizma
Geçen gün wendy williams gösterisini kız arkadaşımla izliyordum ve ev sahibi izleyicilerine ayda en az bir kez tarayıcı geçmişini silmelerini önerdiğinde tamamen dehşete düştü. Tarayıcı geçmişini silmek normalde aşağıdaki etkilere sahiptir:
- Ziyaret edilen web sitelerinin geçmişini siler.
- Çerezleri ve
window.localStorage
(adamım) siler .
Çoğu modern tarayıcı bu seçeneği kolayca kullanılabilir hale getirir, ancak arkadaşlardan korkmaz. Çünkü bir çözüm var. Tarayıcıda komut dosyalarını / resimleri ve diğer şeyleri saklamak için bir önbellek mekanizması vardır. Genellikle geçmişimizi silsek bile, bu tarayıcı önbelleği hala kalır. Tek ihtiyacımız olan verilerimizi burada saklamanın bir yolu. Bunu yapmanın 2 yöntemi vardır. Daha iyisi bir SVG görüntüsü kullanmak ve verilerimizi etiketlerinin içinde saklamaktır. Bu şekilde, flash kullanılarak JavaScript devre dışı bırakılsa bile veriler çıkarılabilir. Ancak bu biraz karmaşık olduğu için JSONP kullanan diğer yaklaşımı göstereceğim ( Wikipedia )
example.com/assets/js/tracking.js (aslında 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);
}
Artık oturum anahtarımızı istediğimiz zaman alabiliriz:
window.__sid || window.localStorage.getItem("sid") || getCookie("sid") || ""
Tracking.js dosyasını tarayıcıya nasıl yapıştırabilirim?
Bunu Cache-Control , Last-Modified ve ETag HTTP başlıklarını kullanarak başarabiliriz . SessionID
Etag üstbilgisi için as değerini kullanabiliriz :
setHeaders({
"ETag": SessionID,
"Last-Modified": new Date(0).toUTCString(),
"Cache-Control": "private, max-age=31536000, s-max-age=31536000, must-revalidate"
})
Last-Modified
üstbilgisi tarayıcıya bu dosyanın temelde hiçbir zaman değiştirilmediğini söyler. Cache-Control
proxy'lere ve ağ geçitlerine belgeyi önbelleğe almamalarını söyler, ancak tarayıcıya 1 yıl boyunca önbelleğe almasını söyler.
Tarayıcı belgeyi bir sonraki istekte bulunduğunda, gönderir If-Modified-Since
ve If-None-Match
üstbilgileri gönderir . Bunları bir iade etmek için kullanabiliriz.304 Not Modified
yanıt .
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();
}
Şimdi tarayıcı her istediğimizde tracking.js
sunucumuz bir 304 Not Modified
sonuca yanıt verecek ve yerel kopyasınıntracking.js
.
Hala anlamıyorum. Bunu bana açıkla
Kullanıcının tarama geçmişini temizlediğini ve sayfayı yenilediğini varsayalım. Kullanıcı bilgisayarında kalan tek şey tracking.js
tarayıcı önbelleğinde bir kopyasıdır . Tarayıcı talep ettiğinde, alınan ilk sürümünü çalıştırmasına neden olan tracking.js
bir 304 Not Modified
yanıt alır tracking.js
. silinmiş tracking.js
olanı yürütür ve geri yükler SessionID
.
onaylama
Haxor X'in hala oturum açtıklarında müşterilerimizin çerezlerini çaldığını varsayalım. Kriptografi ve Tarayıcı kurtarmaya parmak izi. Şunun için orijinal tanımımızı hatırlayın SessionID
:
BrowserID|ComputerID|randomBytes(256)
Bunu şu şekilde değiştirebiliriz:
Timestamp|BrowserID|ComputerID|encrypt(randomBytes(256), hk)|sign(Timestamp|BrowserID|ComputerID|randomBytes(256), hk)
Nerede hk = sign(Timestamp|BrowserID|ComputerID, serverKey)
.
Şimdi SessionID
aşağıdaki algoritmayı kullanarak doğrulayabiliriz :
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;
Şimdi Haxor'un saldırısının çalışması için:
- Aynısı var
ComputerID
. Bu, mağdurla aynı İSS sağlayıcısına sahip olmaları gerektiği anlamına gelir (Tricky). Bu, kurbanımıza kendi ülkesinde yasal işlem yapma fırsatı verecektir. Haxor ayrıca HTTPS oturum anahtarını kurbandan almalıdır (Hard).
- Aynı
BrowserID
. Herkes User-Agent dizesini taklit edebilir (Sinir bozucu).
- Kendi sahte
SessionID
(Çok Sert) oluşturabilir. Birim atamaları çalışmaz çünkü şifreleme / imzalama anahtarı oluşturmak için bir zaman damgası kullanırız, bu temelde her oturum için yeni bir anahtar oluşturmak gibidir. Bunun üzerine rastgele baytları şifreliyoruz, böylece basit bir sözlük saldırısı da söz konusu değil.
Biz yönlendirme ile doğrulama artırabilir GoogleID
ve FingerprintID
kişilere karşı ve eşleştirme (ajax veya gizli alanlar üzerinden).
if( GoogleID != getStoredGoodleID($sid) ) return false;
if( byte_difference(FingerPrintID, getStoredFingerprint($sid) > 10%) return false;