總結一下使用canvas fingerprinting的過程
首先來介紹一下 canvas 指紋的信息
在過去,實現(xiàn)上述cookie是最受歡迎的一種。但由于移動互聯(lián)網(wǎng)的發(fā)展,移動設備限制、用戶禁用cookie。使得cookie愈來愈不受待見。伴隨著html5的成熟,通過canvas fingerprinting技術標識一個唯一的瀏覽器逐漸被接受。它的特點是不通過cookie,用戶基本無法屏蔽它 。
需求分析
一個簡單的需求看這里》》
- 組件名稱:初始以及為空時,默認為【點贊n】,n按照點贊組件的添加順序自增;
- 點贊邏輯:
(1)點贊后,再次點擊可以取消點贊
(2)每個用戶可以點擊一次 - 頁面展示效果:點贊/取消點贊時,顯示心跳的動畫效果。
- 點贊次數(shù)
- 是否登陸
- 登陸了
- 記錄userId判斷是否點贊
- 沒登錄
- 1:會出現(xiàn)的問題:
- 什么時機產(chǎn)生
-
方案一
- 用戶打開頁面,獲取cookie/seesion,生成一個唯一的識別碼
- uuid,儲存下來,前端再進行二次判斷是否此用戶出現(xiàn)過。
-
方案二
- 使用canvas fingerprinter(由前端根據(jù)用戶瀏覽器的各種信息【比如分辨率,瀏覽器設定,瀏覽器版本,硬件資訊等】生成一個canvas)比如獲取瀏覽器的序列號;
-
怎么獲取瀏覽器信息:
結論--canvas fingerprinting帆布指紋技術
使用方案二
-
- 產(chǎn)生以后怎么保證 同一個人映射唯一的 uuid
- 只保證同一個瀏覽器看做一個用戶
- 幾種場景
- 安卓
- 微信
- 各種瀏覽器(chrome,safari,firefox,UC,qq,獵豹,opera,自帶的。。)
- ios
- 微信
- 各種瀏覽器
- pc
- 各種瀏覽器
- ie9-
- 平板
- ipad
- 其他平板
- 可能會出現(xiàn)的問題
- 一個人多刷
- 無痕模式
- 用戶手動清除cookie
- 安卓
- 什么時機產(chǎn)生
- 2 #流程
- 登陸
- 根據(jù)userId判斷是否點贊
- 未登錄
- 用戶打開瀏覽器
- 根據(jù)瀏覽器的各種信息,前端生成一個canvas fingerprinting 圖(一串b64 string代碼)
- 返回給后臺,記錄下來
- 根據(jù)canvas指紋的不同確認未登錄的用戶
- 登陸
- 3 考慮的問題
- 返回的bs64太長,要簡單點 截一段
- 改動canvas使其簡單短一點
- 數(shù)據(jù)類型統(tǒng)一為 string
- 1:會出現(xiàn)的問題:
- 登陸了
》和后臺討論完問題后開始查找資料和擼代碼
其實除了帆船指紋方法還有很多其他的前端的方法用以追蹤用戶信息,我也順便研究了一下??,后面再留鏈接大家看看;
方案一
<script>
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
ctx.font = "24px Arial";
ctx.fillText("Hello Panda",22,33);
ctx.moveTo(0,60);
ctx.lineTo(100,60);
ctx.stroke();
//大家就隨意創(chuàng)建一個canvas標簽就是
var b64 = canvas.toDataURL().replace("data:image/png;base64,","");
//然后用toDataURL方法對生成的canvas圖像進行64碼進制轉換
console.log(b64);
//然后我們打印出來看看效果
</script>
//一開始使用這個產(chǎn)生的代碼
- 效果如下不堪入目,不過幾乎沒有重復率的說
- 下面是效果圖我測試了幾個瀏覽器的不同情況
- chrome
- 正常模式
- [圖片上傳失敗...(image-baf153-1516330888974)]
- 正常模式
- chrome
屏幕快照 2017-02-12 下午10.40.46 1.png
- 隱身模式
- [圖片上傳失敗...(image-bcfd33-1516330888974)]
屏幕快照 2017-02-12 下午11.01.14.png
- firefox
- 正常模式
- [圖片上傳失敗...(image-a1e262-1516330888974)]
屏幕快照 2017-02-13 上午9.53.35.png
- 隱身模式
- [圖片上傳失敗...(image-8ef4d0-1516330888974)](假裝有圖片)
- safari
- 正常模式
- [圖片上傳失敗...(image-c68e76-1516330888974)](假裝有圖片)
- 隱身模式
- [圖片上傳失敗...(image-67e898-1516330888974)](假裝有圖片)
- 經(jīng)過精心的對比,發(fā)現(xiàn)隱身模式和正常模式下的64碼是一致的
- 不信的哥們這里有圖??
- 還有考慮用戶清楚cookie的情況我也做了測試,發(fā)現(xiàn)清楚cookie前后的
- 64位代碼是一致的
- 當然還有其他的各種情況大家自己可以測試一下了;
效果測試還行但是后端的哥們就不同意了,你這字符串也太長了,數(shù)據(jù)庫不好存呀
這簡單咱們就截取一段代碼就是了
下面是方案二
function bin2hex(s) {
// discuss at: http://phpjs.org/functions/bin2hex/
// original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Onno Marsman
// bugfixed by: Linuxworld
// improved by: ntoniazzi (http://phpjs.org/functions/bin2hex:361#comment_177616)
// example 1: bin2hex('Kev');
// returns 1: '4b6576'
// example 2: bin2hex(String.fromCharCode(0x00));
// returns 2: '00'
var i, l, o = '',
n;
s += '';
for (i = 0, l = s.length; i < l; i++) {
n = s.charCodeAt(i)
.toString(16);
o += n.length < 2 ? '0' + n : n;
}
return o;
}
function getUUID(domain) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
ctx.font = "24px Arial";
ctx.fillText("Hello Panda",22,33);
ctx.moveTo(0,60);
ctx.lineTo(100,60);
ctx.stroke();
//大家就隨意創(chuàng)建一個canvas標簽就是
var b64 = canvas.toDataURL().replace("data:image/png;base64,","");
//然后用toDataURL方法對生成的canvas圖像進行64碼進制轉換
//console.log("b64="+b64);
var bin = atob(b64);
//console.log("bin="+bin);bin這里是一張圖片了,解碼圖片
//這里使用js內(nèi)置的 atob()方法將64進制的解碼一下
var crc = bin2hex(bin.slice(-16, -12));
//console.log("crc="+crc)
return crc;
}
//使用atob函數(shù)解碼
//getUUID(string) 寫入一個字符串隨機產(chǎn)生一個八位的字符串標識符
console.log(getUUID("asdfa"))
- 然后現(xiàn)在就生成了一個8位的字符串,好用多了。不過要經(jīng)過嚴密的測試,還怕有重復的,這就要麻煩下后臺的哥們了。測試大家下來也可以自己多搞一下。
- [圖片上傳失敗...(image-9f2a6b-1516330888974)]
最后啦,當然是為了填充getUUID方法獲取用戶的一些關鍵性信息了;
這里貼一些獲取信息的方法,其實還有很多其他的方法可以獲取用戶信息,我們把這些信息打包成一個長字符串,返回到getUUID方法,再打包返回給后臺就大功告成了??;
- 測試圖片:
屏幕快照 2017-02-13 上午10.31.56.png
屏幕快照 2017-02-12 下午11.35.23.png
屏幕快照 2017-02-13 上午10.31.56.png
<!DOCTYPE html>
<head>
<title> New Document </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no">
<meta name="Generator" content="EditPlus">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta charset="utf-8" />
<meta name="Description" content="">
<script id=clientEventHandlersJS language=javascript>
/******************************************下為瀏覽器信息************************************************/
//獲取瀏覽器相關信息
function allinfo() {
var appName = navigator.appName; //瀏覽器的正式名稱
var appVersion = navigator.appVersion; //瀏覽器的版本號
var cookieEnabled = navigator.cookieEnabled; // 返回用戶瀏覽器是否啟用了cookie
var cpuClass = navigator.cpuClass; //返回用戶計算機的cpu的型號,通常intel芯片返回"x86"(火狐沒有)
var mimeType = navigator.mimeTypes; // 瀏覽器支持的所有MIME類型的數(shù)組
var platform = navigator.platform; // 瀏覽器正在運行的操作系統(tǒng)平臺,包括Win16(windows3.x)
// Win32(windows98,Me,NT,2000,xp),Mac68K(Macintosh 680x0)
// 和MacPPC(Macintosh PowerPC)
var plugins = navigator.plugins; // 安裝在瀏覽器上的所有插件的數(shù)組
var userLanguage = navigator.userLanguage; // 用戶在自己的操作系統(tǒng)上設置的語言(火狐沒有)
var userAgent = navigator.userAgent; //包含以下屬性中所有或一部分的字符串:appCodeName,appName,appVersion,language,platform
var systemLanguage = navigator.systemLanguage; // 用戶操作系統(tǒng)支持的默認語言(火狐沒有)
var info = "<table border=1>";
</script>
</head>
<body>
</body>
</html>