最近又又又买了一个新的域名,所以打算在这域名基础上写一个匿名投票用的统计系统(捡鼠标垫买电脑系列)用于一项长期的数据统计(不知道收集到多少数据)。

分析

既然是投票系统,那么就必须对防止刷票做处理。 记得N年以前有个网站投票貌似是关于360的文章,底部有个投票并没有做处理,所以我光靠按键精灵就刷了几千票,不过十几分钟之后貌似被发现了。

所以关于防刷票我能写的就有以下几种方案:

  1. 登陆注册——极大的增加投票所需要的成本,但是又由于成本导致真实用户被拒之门外。
  2. Cookie标记——少量的成本,也容易被清理。
  3. ip限制——没有成本,但是由于NAT的网络环境存在导致无法实行。
  4. ip+UA限制——没有成本,但是可能会出现UA重复的情况。
  5. Canvas Fingerprint——没有成本,极小的重复可能,但是和4一样更换浏览器就可以突破限制。

综上所述似乎Canvas Fingerprint是一个比较合理的选择。

Canvas Fingerprint

Canvas指纹的原理是先使用canvas绘制一张图像,再使用canvas.toDataURL()方法可以获得图像的Base64格式编码,所得的最后一块32位长度的内容就是可以用于识别用户的crc校验码

并且由于Canvas的引入,可以有效的抑制大部分直接对投票接口操作的请求,可以区分机器人和真实用户(不过我还是觉得图形码更有效)

例如使用python尝试获取crc校验码

from bs4 import BeautifulSoup
import requests
html = requests.get("https://browserleaks.com/canvas").text
soup = BeautifulSoup(html,"html5lib")
print(soup.find(id="crc").get_text())

输出结果为n/a

虽然可以使用其当作用户的校验码,但是在同一款浏览器下还是很容易出现重复的,所以需要引入外部变量

fingerprintJS就是优化后的canvas fingerprint项目,国内有人进行过测试,经过优化的canvas指纹的精确度大幅提升。官网声称正确率可以达到94%

使用

引入js

var fingerprint = new Fingerprint().get();

如果你想使用canvas指纹则带入参数canvas: true

var fingerprint = new Fingerprint({canvas: true}).get();

如果想使用基于屏幕分辨率的计算方式则带入参数screen_resolution: true

var fingerprint = new Fingerprint({screen_resolution: true}).get();