200

我需要找出一种唯一标识访问我正在创建的网站的每台计算机的方法。有人对如何实现这一目标有任何建议吗?

因为我希望该解决方案适用于所有机器和所有浏览器(在合理范围内),所以我正在尝试使用 javascript 创建一个解决方案。

饼干不会做。

假设计算机没有发生硬件更改,我需要能够基本上创建一个计算机独有且可重复的 guid。我正在考虑的方向是获取网卡的 MAC 和其他此类信息,这些信息将识别访问该网站的机器。

4

22 回答 22

83

介绍

我不知道是否有或曾经有一种方法可以单独使用浏览器来唯一识别机器。主要原因是:

  • 您需要将数据保存在用户计算机上。用户可以随时删除这些数据。除非您有办法重新创建对每台机器都是唯一的数据,否则您将陷入困境。
  • 验证。您需要防范欺骗、会话劫持等。

即使有办法在不使用 cookie 的情况下跟踪计算机,也总会有绕过它的方法和自动执行此操作的软件。如果您确实需要基于计算机跟踪某些内容,则必须编写本机应用程序(Apple Store / Android Store / Windows Program / 等)。

我可能无法回答您提出的问题,但我可以向您展示如何实施会话跟踪。通过会话跟踪,您尝试跟踪浏览会话而不是访问您网站的计算机。通过跟踪会话,您的数据库架构将如下所示:

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
  }, ...]

基于会话的跟踪的优点:

  1. 对于已登录的用户,您始终可以从用户username//生成相同的会话 ID passwordemail
  2. 您仍然可以使用sessionID.
  3. 即使几个人使用同一台计算机(即网吧),如果他们登录,您也可以分别跟踪他们。

基于会话的跟踪的缺点:

  1. 会话是基于浏览器的,而不是基于计算机的。如果用户使用 2 个不同的浏览器,它将导致 2 个不同的会话。如果这是一个问题,您可以在此处停止阅读。
  2. 如果用户未登录,会话将过期。如果用户未登录,那么他们将使用访客会话,如果用户删除 cookie 和浏览器缓存,该会话将失效。

执行

有很多方法可以实现这一点。我认为我无法涵盖所有​​内容,我只会列出我最喜欢的内容,这将使这是一个固执己见的答案。请记住这一点。

基本

我将使用所谓的永久 cookie 来跟踪会话。即使用户删除他的 cookie 或更新他的浏览器,这些数据也会自动重新创建。但是,用户删除他们的 cookie 和浏览缓存后,它将无法生存。

为了实现这一点,我将使用浏览器缓存机制 ( RFC )、WebStorage API ( MDN ) 和浏览器 cookie(RFCGoogle Analytics)。

合法的

为了使用跟踪 ID,您需要将它们添加到您的隐私政策和使用条款中,最好是在子标题Tracking下。document.cookie我们将在和 上使用以下键window.localStorage

  • _ga:谷歌分析数据
  • __utma : 谷歌分析跟踪 cookie
  • sid : 会话ID

确保在所有使用跟踪的页面上包含指向您的隐私政策和使用条款的链接。

我在哪里存储我的会话数据?

您可以将会话数据存储在您的网站数据库或用户计算机上。由于我通常在使用 3rd 方应用程序(Google Analytics / Clicky / 等)的小型站点(超过 10,000 个连续连接)上工作,因此最好将数据存储在客户端计算机上。这具有以下优点:

  1. 没有数据库查找/开销/负载/延迟/空间/等。
  2. 用户可以随时删除他们的数据,而无需给我写烦人的电子邮件。

和缺点:

  1. 必须对数据进行加密/解密和签名/验证,这会在客户端(还不错)和服务器(呸!)上产生 CPU 开销。
  2. 当用户删除他们的 cookie 和缓存时,数据将被删除。(这才是我真正想要的)
  3. 当用户离线时,数据无法用于分析。(仅针对当前浏览用户的分析)

用户界面

  • BrowserID:从浏览器用户代理字符串生成的唯一 id。Browser|BrowserVersion|OS|OSVersion|Processor|MozzilaMajorVersion|GeckoMajorVersion
  • ComputerID:由用户 IP 地址和 HTTPS 会话密钥生成。 getISP(requestIP)|getHTTPSClientKey()
  • FingerPrintID:基于 JavaScript 的指纹识别,基于修改后的指纹.jsFingerPrint.get()
  • SessionID:用户第一次访问站点时生成的随机密钥。BrowserID|ComputerID|randombytes(256)
  • GoogleID:从__utmacookie 生成。getCookie(__utma).uniqueid

机制

前几天我和女朋友一起看温迪威廉姆斯的节目,当主持人建议她的观众每月至少删除一次浏览器历史记录时,我感到非常震惊。删除浏览器历史记录通常有以下效果:

  1. 删除访问网站的历史记录。
  2. 删除 cookie 和window.localStorage(aww man)。

大多数现代浏览器都使这个选项很容易获得,但不要害怕朋友。因为有解决办法。浏览器有一个缓存机制来存储脚本/图像和其他东西。通常即使我们删除了我们的历史记录,这个浏览器缓存仍然存在。我们所需要的只是一种在此处存储数据的方法。有两种方法可以做到这一点。更好的方法是使用 SVG 图像并将我们的数据存储在其标签中。即使使用 Flash 禁用 JavaScript,这种方式仍然可以提取数据。但是,由于这有点复杂,我将演示使用 JSONP 的另一种方法(维基百科

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);
}

现在我们可以随时获取会话密钥:

window.__sid || window.localStorage.getItem("sid") || getCookie("sid") || ""

如何让 tracking.js 粘在浏览器中?

我们可以使用Cache-ControlLast-ModifiedETag HTTP 标头来实现这一点。我们可以使用SessionIDetag 标头的 as 值:

setHeaders({
  "ETag": SessionID,
  "Last-Modified": new Date(0).toUTCString(),
  "Cache-Control": "private, max-age=31536000, s-max-age=31536000, must-revalidate"
})

Last-Modifiedheader 告诉浏览器这个文件基本上不会被修改。Cache-Control告诉代理和网关不要缓存文档,但告诉浏览器将其缓存 1 年。

下次浏览器请求该文档时,它将发送If-Modified-SinceIf-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();
}

现在每次浏览器请求tracking.js我们的服务器都会响应304 Not Modified结果并强制执行tracking.js.

我还是不明白。给我解释

假设用户清除了他们的浏览历史并刷新了页面。用户计算机上唯一剩下的就是tracking.js浏览器缓存中的副本。当浏览器请求时,它会收到tracking.js一个304 Not Modified响应,导致它执行tracking.js收到的第一个版本。tracking.js执行并恢复SessionID被删除的。

验证

假设 Haxor X 在客户仍处于登录状态时窃取了他们的 cookie。我们如何保护他们?密码学和浏览器指纹来救援。记住我们最初的定义SessionID是:

BrowserID|ComputerID|randomBytes(256)

我们可以将其更改为:

Timestamp|BrowserID|ComputerID|encrypt(randomBytes(256), hk)|sign(Timestamp|BrowserID|ComputerID|randomBytes(256), hk)

哪里hk = sign(Timestamp|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; 

现在,为了让 Haxor 的攻击起作用,他们必须:

  1. 有相同ComputerID的。这意味着他们必须拥有与受害者相同的 ISP 提供商(Tricky)。这将使我们的受害者有机会在他们自己的国家采取法律行动。Haxor 还必须从受害者(Hard)处获取 HTTPS 会话密钥。
  2. 有相同BrowserID的。任何人都可以欺骗用户代理字符串(烦人)。
  3. 能够自己制造假货SessionID(Very Hard)。卷攻击不起作用,因为我们使用时间戳来生成加密/签名密钥,所以基本上它就像为每个会话生成一个新密钥。最重要的是,我们加密了随机字节,所以简单的字典攻击也是不可能的。

我们可以通过转发GoogleIDFingerprintID(通过 ajax 或隐藏字段)和匹配来改进验证。

if( GoogleID != getStoredGoodleID($sid) ) return false;
if( byte_difference(FingerPrintID, getStoredFingerprint($sid) > 10%) return false;
于 2017-01-10T18:14:54.403 回答
58

这些人开发了一种指纹识别方法,可以高度准确地识别用户:

https://panopticlick.eff.org/static/browser-uniqueness.pdf

我们通过根据请求传输到网站的版本和配置信息来调查现代 Web 浏览器受“设备指纹识别”影响的程度。我们实现了一种可能的指纹算法,并从访问我们测试端panopticlick.eff.org的大量浏览器样本中收集了这些指纹 . 我们观察到我们的指纹分布至少包含 18.1 位的熵,这意味着如果我们随机选择一个浏览器,我们最多只能期望 286,777 个其他浏览器中只有一个会共享它的指纹。在支持 Flash 或 Java 的浏览器中,情况更糟,平均浏览器携带至少 18.8 位的识别信息。在我们的样本中,94.2% 的 Flash 或 Java 浏览器是独一无二的。

通过观察回访者,我们估计浏览器指纹随时间变化的速度。在我们的样本中,指纹的变化非常迅速,但即使是简单的启发式算法也通常能够猜测指纹何时是先前观察到的浏览器指纹的“升级”版本,猜测正确率为 99.1%,误报率仅为 0.86% .

我们讨论了浏览器指纹识别在实践中会造成哪些隐私威胁,以及哪些对策可能适合防止它。在防止指纹识别和某些类型的可调试性之间存在权衡,在当前的浏览器中,这些可调试性非常重视隐私。矛盾的是,如果没有足够数量的人使用反指纹隐私技术,它们可能会弄巧成拙。我们表明,一些隐私措施目前成为这个悖论的牺牲品,但其他隐私措施却没有……

于 2010-07-20T07:14:42.807 回答
31

如果没有所有者的合作,就不可能识别访问网站的计算机。但是,如果他们允许您,您可以存储一个 cookie 以在机器再次访问您的站点时对其进行识别。关键是,访客在掌控之中;他们可以随时删除 cookie 并以新访问者的身份出现。

于 2008-10-19T15:42:42.257 回答
30

一种可能性是使用flash cookie

  • 无处不在的可用性(95% 的访问者可能会有闪存)
  • 您可以为每个 cookie 存储更多数据(最多 100 KB)
  • 跨浏览器共享,因此更有可能唯一标识一台机器
  • 清除浏览器 cookie 不会删除 flash cookie。

您需要构建一个小的(隐藏的)Flash 电影来读取和写入它们。

无论您选择何种路线,请确保您的用户选择接受跟踪,否则您将侵犯他们的隐私并成为坏人之一。

于 2008-10-19T16:10:14.323 回答
21

您可能想尝试在 evercookie 中设置一个唯一 ID(它可以跨浏览器工作,请参阅他们的常见问题解答): http ://samy.pl/evercookie/

还有一家名为 ThreatMetrix 的公司被许多大公司用来解决这个问题: http ://threatmetrix.com/our-solutions/solutions-by-product/trustdefender-id/ 它们非常昂贵,而且有些他们的其他产品不是很好,但他们的设备 ID 运行良好。

最后,有这个 panopticlick 想法的开源 jquery 实现: https ://github.com/carlo/jquery-browser-fingerprint 现在看起来很不成熟,但可以扩展。

希望能帮助到你!

于 2012-05-13T18:29:07.917 回答
21

有一种称为画布指纹识别的流行方法,在这篇科学文章中有所描述:The Web Never Forgets: Persistent Tracking Mechanisms in the Wild。一旦你开始寻找它,你会惊讶于它的使用频率。该方法创建了一个唯一的指纹,该指纹对于每个浏览器/硬件组合都是一致的。

本文还回顾了其他持久性跟踪方法,例如 evercookies、重生 http 和 Flash cookie 以及 cookie 同步。

有关画布指纹识别的更多信息:

于 2015-06-16T19:22:43.090 回答
12

您只能通过 HTTP 连接获得少量信息。

  1. IP - 但正如其他人所说,由于 ISP 的动态分配策略,这对于许多(如果不是大多数)互联网用户来说并不是固定的。

  2. 用户代理字符串 - 几乎所有浏览器都会在每个请求中发送他们使用的浏览器类型。但是,这可以由用户在当今的许多浏览器中设置。

  3. 请求字段的集合 - 每个请求都会发送其他字段,例如支持的编码等。如果在聚合中使用这些字段可以帮助标识用户的机器,但同样取决于浏览器并且可以更改。

  4. Cookies - 设置 cookie 是识别机器的另一种方式,或者更具体地说是机器上的浏览器,但正如其他人所说,这些可以被用户删除或关闭,并且仅适用于浏览器,而不是机器。

因此,正确的回答是,您无法仅通过 HTTP over IP 协议实现您的生活。但是,结合使用 cookie、IP 和 HTTP 请求中的字段,您很有可能猜测它是什么机器。用户倾向于只使用一个浏览器,并且通常来自一台机器,所以这可能相当可靠,但这会因受众而异......技术人员更有可能搞砸这些东西,并使用更多的机器/浏览器。此外,这甚至可以与一些尝试对 IP 进行地理定位并使用该数据相结合。但无论如何,没有任何时候都是正确的解决方案。

于 2008-10-19T19:57:35.830 回答
10

cookie 和非 cookie 方法都存在缺陷。但是,如果您可以原谅 cookie 方法的缺点,这里有一个想法。

如果您已经在您的网站上使用 Google Analytics,那么您无需自己编写代码来跟踪唯一用户。__utmaGoogle 文档中所述, Google Analytics 通过 cookie 值为您执行此操作。通过重用此值,您不会创建额外的 cookie 有效负载,这对页面请求具有效率优势。

您可以轻松编写一些代码来访问该值,或使用此脚本的 getUniqueId()功能。

于 2012-08-28T15:18:13.383 回答
8

与之前的解决方案一样,cookie 是一种很好的方法,但请注意它们可以识别浏览器。如果我在 Firefox 中访问了一个网站,然后在 Internet Explorer 中访问了一个网站,cookie 将分别为这两种尝试存储。一些用户还禁用了 cookie(但更多的人禁用了 JavaScript)。

要考虑的另一种方法是 IP 和主机名标识(请注意,对于拨号/非静态 IP 用户,这些可能会有所不同,AOL 也使用一揽子 IP)。但是,由于这仅识别网络,因此可能不如 cookie 有效。

于 2008-10-19T15:50:18.640 回答
6

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...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?

This is a pretty common type of authentication used by banks.

Say you're accessing your bank website via example-isp.com. The first time you're there, you'll be asked for your password, as well as additional authentication. Once you've passed, the bank knows that user "thatisvaliant" is authenticated to access the site via example-isp.com.

In the future, it won't ask for extra authentication (beyond your password) when you're accessing the site via example-isp.com. If you try to access the bank via another-isp.com, the bank will go through the same routine again.

So to summarize, what the bank's identifying is your ISP and/or netblock, based on your IP address. Obviously not every user at your ISP is you, which is why the bank still asks you for your password.

Have you ever had a credit card company call to verify that things are OK when you use a credit card in a different country? Same concept.

于 2008-10-28T23:00:14.813 回答
6

除了使用 cookie 的建议之外,唯一可用于询问的全面识别属性集包含在 HTTP 请求标头中。因此,可以使用其中的一些子集为用户代理(即浏览器)创建伪唯一标识符。此外,这些信息中的大部分可能已经默认记录在 Web 服务器软件的所谓“访问日志”中,如果没有,可以轻松配置为这样做。然后,可以开发一个工具来简单地扫描这个日志的内容,创建指纹每个请求由 IP 地址和用户代理字符串等组成。可用的数据越多,甚至包括特定 cookie 的内容,都会增加该指纹的唯一性质量。虽然,正如许多其他人已经说过的那样,HTTP 协议并没有做到这一点 100% 万无一失——充其量它只能是一个相当好的指标。

于 2008-10-20T02:40:30.200 回答
4

Really, what you want to do cannot be done because the protocols do not allow for this. If static IPs were universally used then you might be able to do it. They are not, so you cannot.

If you really want to identify people, have them log in.

Since they will probably be moving around to different pages on your web site, you need a way to keep track of them as they move about.

So long as they are logged in, and you are tracking their session within your site via cookies/link-parameters/beacons/whatever, you can be pretty sure that they are using the same computer during that time.

Ultimately, it is incorrect to say this tells you which computer they are using if your users are not using your own local network and do not have static IP addresses.

If what you want to do is being done with the cooperation of the users and there is only one user per cookie and they use a single web browser, just use a cookie.

于 2008-10-19T17:32:05.920 回答
4

您可以使用指纹js2

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 相似性,因此即使他们的指纹发生变异,您仍然可以跟踪他们

于 2018-03-13T08:49:26.617 回答
3

因为我希望该解决方案适用于所有机器和所有浏览器(在合理范围内),所以我正在尝试使用 javascript 创建一个解决方案。

这难道不是不使用 javascript的一个很好的理由吗?

正如其他人所说 - cookie 可能是您的最佳选择 - 请注意这些限制。

于 2008-10-19T16:26:24.743 回答
2

我想结论是我无法以编程方式唯一地识别正在访问我的网站的计算机。

我有以下问题。当我使用一台从未访问过我的网上银行网站的机器时,我会被要求进行额外的身份验证。然后,如果我第二次回到网上银行网站,我不会被要求额外的身份验证。阅读我的问题的答案后,我决定一定是涉及到 cookie。因此,我删除了 IE 中的所有 cookie 并重新登录我的网上银行网站,完全期待再次被问到身份验证问题。令我惊讶的是,我没有被问到。这不会让人相信银行正在做某种不涉及 cookie 的 pc 标记吗?

此外,今天经过大量谷歌搜索后,我发现以下公司声称销售一种解决方案,该解决方案可以唯一识别访问网站的机器。http://www.the41.com/products.asp

如果您能进一步澄清我发现的这些相互矛盾的信息,我将不胜感激,我将不胜感激。

于 2008-10-20T01:29:20.543 回答
2

Cookie 对确定唯一身份访问者没有用处。用户可以清除 cookie 并刷新站点 - 然后他再次被归类为新用户。

我认为最好的方法是实现服务器端解决方案(因为您需要在某个地方存储数据)。根据您对此类数据的需求的复杂性,您将需要确定什么被归类为唯一访问。一个明智的方法是允许 IP 地址在第二天返回并获得唯一的访问。一天内来自一个 IP 地址的多次访问不应算作唯一访问。

例如,使用 PHP,获取访问者的 IP 地址并将其存储在文本文件(或 sql 数据库)中是微不足道的。

服务器端解决方案适用于所有机器,因为您将在用户首次加载您的网站时对其进行跟踪。不要使用 javascript,因为它是用于客户端脚本的,而且用户可能在任何情况下都禁用了它。

希望有帮助。

于 2008-10-19T15:49:37.843 回答
2

我会结合使用 cookie 和 flash cookie 来做到这一点。创建一个 GUID 并将其存储在 cookie 中。如果 cookie 不存在,请尝试从 flash cookie 中读取。如果仍未找到,请创建它并将其写入 Flash cookie。这样,您可以跨浏览器共享相同的 GUID。

于 2008-11-05T19:08:43.727 回答
1

我认为 cookie 可能是您正在寻找的东西;这就是大多数网站唯一识别访问者的方式。

于 2008-10-19T15:36:56.670 回答
0

Assuming you don't want the user to be in control, you can't. The web doesn't work like that, the best you can hope for is some heuristics.

If it is an option to force your visitor to install some software and use TCPA you may be able to pull something off.

于 2008-10-19T17:18:09.833 回答
0

我将给出我的想法,从简单到复杂。在以上所有内容中,您都可以创建会话,并且问题本质上转化为将会话与请求匹配。

a)(难度:容易)使用客户端硬件显式存储某种会话ID/哈希(存在相当多的隐私/安全问题,因此请确保您对存储的任何内容进行哈希处理),解决方案包括:

  • 饼干存储
  • 浏览器存储/webDB/(更奇特的浏览器解决方案)
  • 具有将内容存储在文件中的权限的扩展名。

上面的问题是用户可以清空他的缓存以防万一。

b)(难度:中等)基于登录的身份验证。大多数现代 Web 框架都提供了这样的解决方案,其核心思想是让用户自愿识别自己,这很简单,但会增加架构的复杂性。

上述内容具有额外的复杂性,并且基本上是非公开内容。

c)(难度:hard -R&D)基于元数据的识别,(浏览器 ip/语言/浏览器/和其他隐私入侵的东西,所以确保你让你的用户知道,否则你可能会被起诉)不完美的解决方案可能会变得更复杂(a用户以特定频率键入或使用具有特定模式的鼠标?您甚至可以应用 ML 解决方案)。声称的解决方案

最强大的用户甚至不需要明确地识别他。这是对隐私的直接侵犯(参见 GDPR),并不完美,例如。ip可以改变。

于 2021-02-28T13:24:51.047 回答
-1

我的帖子可能不是一个解决方案,但我可以提供一个示例,该功能已实现。

如果您www.supertorrents.org是第一次从您的计算机访问注册页面,那很好。但是,如果您刷新页面或再次打开该页面,则表明您之前访问过该页面。真正的美在这里 - 即使您重新安装 Windows 或其他操作系统,它也能识别。

我在某处读到他们存储 CPU ID。虽然我找不到他们是怎么做到的,但我严重怀疑,他们可能会使用 MAC 地址来做到这一点。

如果我找到方法,我一定会分享。

于 2013-05-04T17:04:02.203 回答
-2

一个恶作剧:

  1. 创建 2 个注册页面:

    第一个注册页面:无需任何电子邮件或安全检查(仅使用用户名和密码)

    第二注册页面:具有高安全级别(电子邮件验证请求和安全图像等)

  2. 为了让客户满意,方便注册,默认注册页面应该是(First Registration Page),但在 (First Registration Page)有一个隐藏的限制。是IP限制。如果 IP 尝试第二次注册(例如少于 1 小时)而不是显示阻止页面。您可以自动显示(第二注册页面)

  3. (首次注册页面)中,您可以设置(例如:在 1 小时或 24 小时内阻止来自 1 个 IP 的 2 次尝试)并且在(例如)1 小时后,您可以自动打开来自该 IP 的访问

请注意:(第一个注册页面)(第二个注册页面)不应分开页面。你只做了一页。(例如:register.php)并使其在第一 PHP 样式和第二 PHP 样式之间切换变得智能

于 2016-11-06T13:36:32.777 回答