我需要找出一种方法,唯一地识别每台计算机访问我正在创建的网站。有人有什么建议吗?
因为我想解决方案工作在所有机器和所有浏览器(在合理的范围内),我试图使用javascript创建一个解决方案。
饼干可不行。
我需要基本上创建一个guid的能力,这是唯一的计算机和可重复的,假设没有硬件变化发生在计算机上。我正在考虑的方向是获得网卡的MAC和这种性质的其他信息,这将id访问网站的机器。
我需要找出一种方法,唯一地识别每台计算机访问我正在创建的网站。有人有什么建议吗?
因为我想解决方案工作在所有机器和所有浏览器(在合理的范围内),我试图使用javascript创建一个解决方案。
饼干可不行。
我需要基本上创建一个guid的能力,这是唯一的计算机和可重复的,假设没有硬件变化发生在计算机上。我正在考虑的方向是获得网卡的MAC和这种性质的其他信息,这将id访问网站的机器。
当前回答
您可以使用fingerprintjs2
new Fingerprint2().get(function(result, components) {
console.log(result) // a hash, representing your device fingerprint
console.log(components) // an array of FP components
//submit hash and JSON object to the server
})
在此之后,您可以根据现有用户检查所有用户并检查JSON相似性,因此即使他们的指纹发生了突变,您仍然可以跟踪他们
其他回答
我猜结论是我不能通过编程唯一地识别一台正在访问我的网站的计算机。
I have the following question. When i use a machine which has never visited my online banking web site i get asked for additional authentification. then, if i go back a second time to the online banking site i dont get asked the additional authentification. reading the answers to my question i decided it must be a cookie involved. therefore, i deleted all cookies in IE and relogged onto my online banking site fully expecting to be asked the authentification questions again. to my surprise i was not asked. doesnt this lead one to believe the bank is doing some kind of pc tagging which doesnt involve cookies?
此外,今天在谷歌搜索了很多之后,我发现了以下公司,他们声称出售一种解决方案,可以唯一地识别访问网站的机器。http://www.the41.com/products.asp。
我很感激所有好的信息,如果你能进一步澄清这些相互矛盾的信息,我将非常感激。
当我使用一台从未访问过我的网上银行网站的机器时,我被要求进行额外的身份验证。然后,如果我第二次回到网上银行网站,我不会被要求额外的身份验证……我删除了IE中的所有cookie,并重新登录到我的网上银行网站,完全期待再次被问到身份验证问题。令我吃惊的是,没有人问我。这难道不会让人相信银行正在做某种不涉及cookie的PC标记吗?
这是银行使用的一种非常常见的身份验证类型。
假设您正在通过example-isp.com访问您的银行网站。第一次登录时,系统会要求您输入密码,并进行额外的身份验证。一旦您通过了认证,银行就知道用户“thatisvaliant”已通过身份验证,可以通过example-isp.com访问该网站。
将来,当您通过example-isp.com访问该网站时,它将不会要求额外的身份验证(除了您的密码)。如果您试图通过another-isp.com访问该银行,该银行将再次执行相同的程序。
总之,银行识别的是你的ISP和/或网络块,基于你的IP地址。显然,ISP上的每个用户都不是你,这就是为什么银行仍然要求你输入密码的原因。
当你在另一个国家使用信用卡时,你有没有接到信用卡公司的电话来核实事情是否正常?相同的概念。
如果没有用户的合作,识别访问网站的电脑是不可能的。但是,如果他们允许,您可以存储一个cookie,以便在机器再次访问您的网站时识别它。关键在于,访问者是可控的;他们可以删除cookie,并随时以新访客的身份出现。
你可能想尝试在evercookie中设置一个唯一的ID(它可以跨浏览器工作,见他们的常见问题): http://samy.pl/evercookie/
还有一家叫做ThreatMetrix的公司,被很多大公司用来解决这个问题: http://threatmetrix.com/our-solutions/solutions-by-product/trustdefender-id/ 它们相当昂贵,而且他们的其他一些产品也不太好,但他们的设备id运行良好。
最后,还有这个开源jquery实现的panopticlick的想法: https://github.com/carlo/jquery-browser-fingerprint 它现在看起来很不成熟,但可以扩展。
希望能有所帮助!
简介
我不知道是否有一种方法可以单独使用浏览器来唯一地识别机器。主要原因有:
您需要在用户计算机上保存数据。这个数据可以是 用户可以随时删除。除非你有办法重现这个 每台机器的数据都是独一无二的,那么你就会陷入困境。 验证。您需要防范欺骗、会话劫持等。
即使有不使用cookie的方法来跟踪计算机,也总有办法绕过它,软件会自动做到这一点。如果你真的需要在计算机上跟踪一些东西,你就必须写一个本地应用程序(苹果商店/安卓商店/ Windows程序等)。
我可能不能给你你问的问题的答案,但我可以告诉你如何实现会话跟踪。使用会话跟踪,您可以尝试跟踪浏览会话,而不是计算机访问您的网站。通过跟踪会话,您的数据库模式将如下所示:
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
}, ...]
基于会话跟踪的优点:
对于已登录的用户,您总是可以从用户的用户名/密码/电子邮件生成相同的会话id。 您仍然可以使用sessionID跟踪来宾用户。 即使几个人使用同一台电脑(例如网吧),如果他们登录,你也可以分别跟踪他们。
基于会话跟踪的缺点:
会话是基于浏览器而不是基于计算机的。如果一个用户使用2个不同的浏览器,它将导致2个不同的会话。如果这是一个问题,你可以停止阅读这里。 如果用户没有登录,会话将过期。如果用户没有登录,那么他们将使用一个来宾会话,如果用户删除cookie和浏览器缓存,该会话将失效。
实现
有许多方法可以实现这一点。我不认为我能涵盖所有,我只列出我最喜欢的,这将使这成为一个固执己见的答案。记住这一点。
基础知识
我将使用所谓的永久cookie来跟踪会话。即使用户删除了他的cookie或更新了他的浏览器,这些数据也会自动恢复。然而,当用户删除他们的cookie和浏览缓存时,它将无法存活。
为了实现这一点,我将使用浏览器缓存机制(RFC), WebStorage API (MDN)和浏览器cookie (RFC,谷歌Analytics)。
法律
为了使用跟踪id,您需要将它们添加到您的隐私政策和使用条款中,最好是在跟踪子标题下。我们将在两个文档上使用以下键。cookie和window.localStorage:
_ga:谷歌分析数据 __utma:谷歌分析跟踪cookie 席德:SessionID
确保在所有使用跟踪功能的页面上包含指向您的隐私政策和使用条款的链接。
会话数据存储在哪里?
您可以将会话数据存储在网站数据库中或用户计算机上。因为我通常在使用第三方应用程序(谷歌Analytics / Clicky / etc)的较小网站(让超过10,000个连续连接)上工作,所以对我来说,最好将数据存储在客户端计算机上。这样做有以下优点:
没有数据库查找/开销/负载/延迟/空间等。 用户可以随时删除他们的数据,而无需给我写烦人的电子邮件。
优缺点:
必须对数据进行加密/解密和签名/验证,这会在客户端和服务器上产生cpu开销(不是很糟糕)。 当用户删除他们的cookie和缓存时,数据将被删除。(这是我真正想要的) 当用户离线时,数据无法用于分析。(仅针对当前浏览用户的分析)
UUIDS
BrowserID: Unique id generated from the browsers user agent string. Browser|BrowserVersion|OS|OSVersion|Processor|MozzilaMajorVersion|GeckoMajorVersion ComputerID: Generated from users IP Address and HTTPS session key. getISP(requestIP)|getHTTPSClientKey() FingerPrintID: JavaScript based fingerprinting based on a modified fingerprint.js. FingerPrint.get() SessionID: Random key generated when user 1st visits site. BrowserID|ComputerID|randombytes(256) GoogleID: Generated from __utma cookie. getCookie(__utma).uniqueid
机制
前几天,我和女朋友一起看wendy williams的节目,主持人建议她的观众至少每月删除一次浏览器历史记录,这让我完全震惊了。删除浏览器历史记录通常有以下效果:
删除访问网站的历史记录。 删除cookie和窗口。localStorage (aww man)。
Most modern browsers make this option readily available but fear not friends. For there is a solution. The browser has a caching mechanism to store scripts / images and other things. Usually even if we delete our history, this browser cache still remains. All we need is a way to store our data here. There are 2 methods of doing this. The better one is to use a SVG image and store our data inside its tags. This way data can still be extracted even if JavaScript is disabled using flash. However since that is a bit complicated I will demonstrate the other approach which uses JSONP (Wikipedia)
Example.com/assets/js/tracking.js(实际上是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);
}
现在我们可以在任何时候获得会话密钥:
窗口。__sid || window.localStorage.getItem("sid") || getCookie("sid") || "" "
我如何让跟踪。js坚持在浏览器?
我们可以使用Cache-Control, Last-Modified和ETag HTTP头来实现这一点。我们可以使用SessionID作为etag头的值:
setHeaders({
"ETag": SessionID,
"Last-Modified": new Date(0).toUTCString(),
"Cache-Control": "private, max-age=31536000, s-max-age=31536000, must-revalidate"
})
Last-Modified头文件告诉浏览器这个文件基本上从未被修改过。cache - control告诉代理和网关不缓存文档,但告诉浏览器缓存1年。
下次浏览器请求文档时,它将发送If-Modified-Since和If-None-Match标头。我们可以使用它们返回一个304 Not Modified响应。
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();
}
现在,每次浏览器请求trace .js时,我们的服务器都会响应一个304 Not Modified结果,并强制执行trace .js的本地副本。
我还是不明白。给我解释一下
假设用户清除了他们的浏览历史并刷新了页面。用户计算机上只剩下浏览器缓存中的tracking.js副本。当浏览器请求tracking.js时,它会收到一个304 Not Modified响应,这导致它执行它收到的第一个版本的tracking.js。trace .js执行并恢复被删除的SessionID。
验证
假设Haxor X在客户仍在登录时窃取了他们的cookie。我们如何保护他们?密码学和浏览器指纹来拯救。还记得我们最初对SessionID的定义是:
BrowserID|ComputerID|randomBytes(256)
我们可以更改为:
Timestamp|BrowserID|ComputerID|encrypt(randomBytes(256), hk)|sign(Timestamp|BrowserID|ComputerID|randomBytes(256), hk)
Where hk = sign(时间戳|BrowserID|ComputerID, serverKey)。
现在我们可以使用下面的算法来验证我们的SessionID:
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;
为了让哈克索的攻击奏效他们必须:
Have same ComputerID. That means they have to have the same ISP provider as victim (Tricky). This will give our victim the opportunity to take legal action in their own country. Haxor must also obtain HTTPS session key from victim (Hard). Have same BrowserID. Anyone can spoof User-Agent string (Annoying). Be able to create their own fake SessionID (Very Hard). Volume atacks won't work because we use a time-stamp to generate encryption / signing key so basically its like generating a new key for each session. On top of that we encrypt random bytes so a simple dictionary attack is also out of the question.
我们可以通过转发GoogleID和FingerprintID(通过ajax或隐藏字段)并根据它们进行匹配来改进验证。
if( GoogleID != getStoredGoodleID($sid) ) return false;
if( byte_difference(FingerPrintID, getStoredFingerprint($sid) > 10%) return false;