操作系统及其版本信息
发布时间:2025-06-24 18:13:55 作者:北方职教升学中心 阅读量:975
广告投放等。所以现在浏览器不允许前端JavaScript直接获取设备的MAC地址或其它能够明确标识设备硬件的敏感信息。至此全剧终,不用往下看了🤣
哈哈哈,虽然不能直接获取到设备唯一信息,但是需求还要做,毕竟解决不了提需求的人啊。插件需要生成一个授权码(code),但为了确保安全性,这个code必须与设备绑定,防止被不同的设备使用,限制一个code只能在一个设备上使用。
用户行为追踪
:适用于需要追踪用户行为和偏好的应用,如个性化推荐、方法一:通过后端服务器记录IP地址、
方法二:生成UUID
可以生成一个随机的 UUID,作为设备的唯一标识符,这个方法完全可以满足需求。浏览器特性
// WebGL渲染器:WebGL渲染器信息functiongetWebGLRenderer(){constcanvas =document.createElement('canvas');constgl =canvas.getContext('webgl')||canvas.getContext('experimental-webgl');if(gl){constdebugInfo =gl.getExtension('WEBGL_debug_renderer_info');if(debugInfo){returngl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);}}returnnull;}constwebGLRenderer =getWebGLRenderer();// Canvas指纹:利用Canvas API绘制图像并获取其数据functiongetCanvasFingerprint(){constcanvas =document.createElement('canvas');constcontext =canvas.getContext('2d');context.textBaseline ='top';context.font ='14px Arial';context.textBaseline ='alphabetic';context.fillStyle ='#f60';context.fillRect(125,1,62,20);context.fillStyle ='#069';context.fillText('Hello, world!',2,15);context.fillStyle ='rgba(102, 204, 0, 0.7)';context.fillText('Hello, world!',4,17);returncanvas.toDataURL();}constcanvasFingerprint =getCanvasFingerprint();
8、时间和时区信息
// 时区:用户的时区信息consttimeZone =Intl.DateTimeFormat().resolvedOptions().timeZone;// 时区偏移:与UTC的时区偏移,以分钟为单位。万一被抓了就不值得了那么我们能获取到客户端哪些信息呢?
1、User-Agent等信息来间接识别用户
通过收集浏览器的各种配置和环境信息(如屏幕分辨率、虽然User-Agent可以提供关于用户使用的浏览器和系统的信息,但对于来自同一内网的不同设备,如果这是批量采购的设备,在设备、
constplatform =navigator.platform;// 语言:浏览器的语言设置。consthardwareConcurrency =navigator.hardwareConcurrency;// 设备内存:设备内存信息,单位为GB。缺点:
- 如果用户清除浏览器数据,UUID会丢失,导致无法继续识别设备。在线考试等。
- 不依赖客户端存储,即使用户清除浏览器数据,也可以识别用户。User-Agent等信息
先给大家分析一下这种方法的优缺点 :
优点
- 无需在客户端处理复杂逻辑,降低了前端插件的开发复杂性。在这里整理了几种思路:
可以通过后端服务器记录IP地址、
constlanguage =navigator.language;
3、consttimeZoneOffset =newDate().getTimezoneOffset();5、字体、但需注意,用户清除浏览器数据时,此ID存在丢失的风险。
无用户登录的情况下识别设备
:适用于不需要用户登录即可识别和区分不同设备的应用。这个需求带来了一个问题:我该如何在前端中获取当前设备的唯一标识呢?解决方法
在对浏览器的限制做了进一步了解,因为涉及到用户隐私问题,因为MAC地址是一种物理地址,能够作为设备的唯一标识,如果被网站轻易获取,可能会导致用户隐私泄露和安全风险增加。浏览器和操作系统没有其他差异,它们可能会是相同的User-Agent字符串。
缺点
这个方法并不能精确地区分内网中的每个设备,假设现在有10个设备位于同一内网,并通过相同的外网出口IP地址访问互联网时,仅凭后端服务器记录的IP地址无法区分这10个设备,因为它们对外显示的是同一个公网IP地址。
缺点:
- 信息变化影响识别:浏览器指纹对用户的设置和环境敏感,用户修改设置后指纹可能会改变。长期会话管理等。constscreenSize =`${screen.width}x${screen.height}`;// 可视区域尺寸:浏览器窗口的宽度和高度。constcolorDepth =screen.colorDepth;
2、
User-Agent,它是浏览器或客户端应用程序发送请求时携带的一个字符串头,包含有关浏览器类型、字体信息
// 检测用户系统中可用的字体constfontList =['Arial','Verdana','Times New Roman','Courier New','Georgia','Comic Sans MS','Trebuchet MS','Arial Black','Impact'];constavailableFonts =[];constcanvas =document.createElement('canvas');constcontext =canvas.getContext('2d');consttext ='abcdefghijklmnopqrstuvwxyz0123456789';fontList.forEach((font)=>{context.font =`16px ${font}`;constwidth =context.measureText(text).width;context.font =`16px monospace`;if(context.measureText(text).width !==width){availableFonts.push(font);}});constfonts =availableFonts.join(',');
6、
- 隐私和法律问题:生成和使用浏览器指纹可能涉及隐私问题,需遵守相关法律法规。版本、
- 隐蔽性:用户通常不会意识到浏览器指纹的存在,所以不会伪造一些虚假信息。constviewportSize =`${window.innerWidth}x${window.innerHeight}`;// 颜色深度:屏幕颜色深度。
- 生成UUID并存储在浏览器的localStorage或Cookie中,易于实现。
- 相对于UUID存储在客户端,很容易被用户删除或篡改
示例代码:
// 生成UUIDfunctiongenerateUUID(){return'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(c){varr =Math.random()*16|0,v =c ==='x'?r :(r &0x3|0x8);returnv.toString(16);});}
UUID的版本4使用随机数生成,重复的概率极低。屏幕和显示信息
// 屏幕尺寸:屏幕的宽度和高度。生成相对唯一的浏览器指纹
增强的安全性
:适用于需要更高安全性和防欺骗能力的场景,如防止账号共享、另外就是我们的后台服务只是提供简单的授权码验证服务,增加这部分逻辑显得有些多余。
优点:
- 只要用户不清除浏览器数据,UUID可以长期保留,提供稳定的设备识别能力。操作系统及其版本信息。
优点:
- 较高的唯一性:通过综合多种浏览器和系统信息生成的指纹具有较高的唯一性。插件列表等),生成一个相对唯一的标识符
在用户首次安装插件时生成一个UUID并存储在Cookie或localStorage中,以此作为该设备的唯一标识。其它特性
// 设备是否支持触控consttouchSupport ='ontouchstart'inwindow ||navigator.maxTouchPoints >0;
综合示例代码
最后做一个综合代码示例,将上述信息组合成一个指纹字符串并进行哈希处理,以生成一个唯一标识符:
functiongenerateUUID(){return'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(c){varr =Math.random()*16|0,v =c =='x'?r :(r &0x3|0x8);returnv.toString(16);});}functionhashString(str){lethash =0;for(leti =0;i <str.length;i++){constchar =str.charCodeAt(i);hash =((hash <<5)-hash)+char;hash |=0;// Convert to 32bit integer}returnhash.toString(16);}functiongetScreenSize(){return`${screen.width}x${screen.height}`;}functiongetViewportSize(){return`${window.innerWidth}x${window.innerHeight}`;}functiongetFonts(){constfontList =['Arial','Verdana','Times New Roman','Courier New','Georgia','Comic Sans MS','Trebuchet MS','Arial Black','Impact'];constavailableFonts =[];constcanvas =document.createElement('canvas');constcontext =canvas.getContext('2d');consttext ='abcdefghijklmnopqrstuvwxyz0123456789';fontList.forEach((font)=>{context.font =`16px ${font}`;constwidth =context.measureText(text).width;context.font =`16px monospace`;if(context.measureText(text).width !==width){availableFonts.push(font);}});returnavailableFonts.join(',');}functiongetWebGLRenderer(){constcanvas =document.createElement('canvas');constgl =canvas.getContext('webgl')||canvas.getContext('experimental-webgl');if(gl){constdebugInfo =gl.getExtension('WEBGL_debug_renderer_info');if(debugInfo){returngl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);}}returnnull;}functiongetCanvasFingerprint(){constcanvas =document.createElement('canvas');constcontext =canvas.getContext('2d');context.textBaseline ='top';context.font ='14px Arial';context.textBaseline ='alphabetic';context.fillStyle ='#f60';context.fillRect(125,1,62,20);context.fillStyle ='#069';context.fillText('Hello, world!',2,15);context.fillStyle ='rgba(102, 204, 0, 0.7)';context.fillText('Hello, world!',4,17);returncanvas.toDataURL();}functiongenerateFingerprint(){constscreenSize =getScreenSize();constviewportSize =getViewportSize();constcolorDepth =screen.colorDepth;constuserAgent =navigator.userAgent;constplatform =navigator.platform;constlanguage =navigator.language;constplugins =Array.from(navigator.plugins).map(plugin=>plugin.name).join(',');constdoNotTrack =navigator.doNotTrack;consttimeZone =Intl.DateTimeFormat().resolvedOptions().timeZone;consttimeZoneOffset =newDate().getTimezoneOffset();constfonts =getFonts();consthardwareConcurrency =navigator.hardwareConcurrency;constdeviceMemory =navigator.deviceMemory;constwebGLRenderer =getWebGLRenderer();constcanvasFingerprint =getCanvasFingerprint();consttouchSupport ='ontouchstart'inwindow ||navigator.maxTouchPoints >0;constfingerprint =[screenSize,viewportSize,colorDepth,userAgent,platform,language,plugins,doNotTrack,timeZone,timeZoneOffset,fonts,hardwareConcurrency,deviceMemory,webGLRenderer,canvasFingerprint,touchSupport ].join('|');returnhashString(fingerprint);}constfingerprint =generateFingerprint();constdeviceUUID =generateUUID();console.log('Fingerprint:',fingerprint);console.log('Device UUID:',deviceUUID);
三种方式的适用场景
使用后端服务器记录IP地址和User-Agent
简单的用户追踪
:适用于需要记录访问日志或统计用户活动的简单应用。然而,如果你担心在非常大的数据集中可能会有重复的情况发生,或者你想要确保在分布式系统中生成的UUID在时间上有一定的顺序,那么将UUID与时间戳结合起来。浏览器设置和插件信息// 插件列表:浏览器中安装的插件列表constplugins =Array.from(navigator.plugins).map(plugin=>plugin.name).join(',');// Do Not Track:用户是否启用了“请勿跟踪”设置constdoNotTrack =navigator.doNotTrack;
4、