Как отследить пользователя, чтобы он не гадил, к примеру, в отзывах более одного раза?
Неопытый вебмастер ответит, что для этого существуют cookie, определение IP и данные о браузере(системе).
Способы довольно популярны и как вытекающее из этого — знакомы основной массе пользователей. Теперь юзеры пошли грамотные, и знают, что можно «очистить кеш браузера»(вместе с куками), отключиться и заново включиться в сеть — провайдер назначит новый IP-адрес…
А есть ещё пару моментов, которые можно проверить у пользователя, «выщемив» его таким образом на уникальность.
1. Определяем установленные в системе пользователя шрифты.
Сама по себе политика безопасности не подразумевает получение при помощи Javascript данных о шрифтах. Поэтому как всегда нам придётся смастерить свой велик.
Принцип следующий. Создаём спанку с огромным текстом шрифта по умолчанию(введём asdasd и тк такого шрифта быть по идее не должно, то браузер установит font в дефолт) и набораем десяток букв(лучше использовать самые большие по ширине):
mmmmmmmmwwwww
mmmmmmmmwwwww
Теперь яваскрипту не составит труда подсчитать ширину спанки:
var width = $('span').width();
И ещё. Нас ведь посути не интересует наличие или отсуствие какого-то конкретного шрифта, поэтому смиримся, что дефолтный шрифт(например sans-serif) не определится.
Резльтаты в Firefox: w=700; в Chrome: w=700; в IE7: w=727. В IE как видим значения отличаются, потому что IE — это IE и у него по умолчанию шрифт arial. У Вас результаты могут быть отличны от моих:
Теперь можно скачать вот этот массив шрифтов (около 2000) и в цикле проверять какой шрифт отличается от дефолтной ширины. Таким образом у меня определилась половина установленных в системе шрифтов.
Можно сделать хэш — создать массив совпадений, склеить его в строку и передать серверу, где он высчитает его md5:
var fonts = [1,0,0,0,1,0,1,1,0,1,0,0,0,1,1,1...]; $.post('/index.php', {a: fonts.join('')});
Но это способ для настоящих джедаев. Он немного геморный и займёт некоторое время выполнения.
Я Вас обрадую, что ещё можно получить список шрифтов пользователя при помощи Flash-ролика:
var user_fonts = TextField.getFontList(); getURL("javascript:fontList(\"" + escape(user_fonts) + "\")", "_self");
Как это работает.
Скачать ролик swf
Подключаем к странице ролик, например, при помощи плагина JQuery(кстати, произносится правильно «джейкуери«, а не «джейкуари»):
$("#flashcontent").flash( { "src": "/uploads/010711/2115fonts2.swf", "width": "1", "height": "1", "swliveconnect": "true", "id": "flashfontshelper", "name": "flashfontshelper" }, { update: false } );
и создаём функцию на javascript, которая будет запускаться этим роликом, передавая ей строку со шрифтами:
fontList(fonts){ $.post("/auth", {fonts: fonts}); // отправляем шрифты пользователя на сервер, где можем сгенерировать уникальный хэш }
Вот, к примеру, как отработал скрипт для определения Ваших шрифтов:
2. Определяем установленные в системе пользователя плагины — flash, java и тд
Вот функция, которая возвращает установленные в системе пользователя плагины:
function identify_plugins(){ // fetch and serialize plugins var plugins = ""; // in Mozilla and in fact most non-IE browsers, this is easy if (navigator.plugins) { var np = navigator.plugins; var plist = new Array(); // sorting navigator.plugins is a right royal pain // but it seems to be necessary because their order // is non-constant in some browsers for (var i = 0; i < np.length; i++) { plist[i] = np[i].name + "; "; plist[i] += np[i].description + "; "; plist[i] += np[i].filename + ";"; for (var n = 0; n < np[i].length; n++) { plist[i] += " (" + np[i][n].description +"; "+ np[i][n].type + "; "+ np[i][n].suffixes + ")"; } plist[i] += ". "; } plist.sort(); for (i = 0; i < np.length; i++) plugins+= "Plugin "+i+": " + plist[i]; } // in IE, things are much harder; we use PluginDetect to get less // information (only the plugins listed below & their version numbers) if (plugins == "") { var pp = new Array(); pp[0] = "Java"; pp[1] = "QuickTime"; pp[2] = "DevalVR"; pp[3] = "Shockwave"; pp[4] = "Flash"; pp[5] = "WindowsMediaplayer"; pp[6] = "Silverlight"; pp[7] = "VLC"; var version; for ( p in pp ) { version = PluginDetect.getVersion(pp[p]); if (version) plugins += pp[p] + " " + version + "; " } plugins += ieAcrobatVersion(); } return plugins; }
Вызываем её и получаем:
3. Некоторые другие приметы пользователя.
Узнать на сколько отличается время пользователя от всемирного, сек:
var timezone = new Date().getTimezoneOffset(); // например у меня в Беларуси '-240'
Узнать разрешение экрана пользователя:
var video = screen.width+"x"+screen.height+"x"+screen.colorDepth; // например '1440x900x24'
p.s. В скором будущем все эти приёмы не понадобятся, т.к. грядёт эра нового протокола TCP/IP v6 и пророчат уникальный IP каждому устройству. Выглядеть они будут вот так: 2620:0:1cfe:face:b00c:0:0:3 вместо теперешних таких: 178.126.203.183