Nodejs如何获得客户端的mac地址呢?或者说如何区分客户端的唯一性

Nodejs如何获得客户端的mac地址呢?或者说如何区分客户端的唯一性

请教大神nodejs如何获得客户端的mac地址。 或者说如何区分客户端的唯一性

31 回复

请教大神nodejs如何获得客户端的mac地址。 或者说如何区分客户端的唯一性


WAN没办法获取mac地址的(除非客户端自己把mac地址加到http头)

  1. 在http/tcp的交互过程中是通过ip来通讯的,而mac地址是物理层的,每个数据包会先把mac地址解析成ip再发送
  2. 再LAN环境下,可以通过ARP协议来获取,简单的说就是每台计算机都有一个ip到mac的表,如果表里面有就直接返回,如果表里面没有,也只会在LAN环境下发广播来获取数据

你可以在客户端获取mac地址后加在http头里面返回

在Node.js中直接获取客户端的MAC地址是比较困难的,因为浏览器并不提供这种级别的网络信息。但是,你可以通过其他方式来区分客户端的唯一性,比如使用设备指纹(Device Fingerprinting)或者利用Cookie、LocalStorage等存储机制。

方法一:使用设备指纹

设备指纹是一种通过收集用户设备的各种特征来创建一个唯一的标识符的方法。这些特征包括但不限于屏幕分辨率、时区、浏览器类型、插件、字体等。

示例代码:

const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json());

function getDeviceFingerprint(req) {
    const { headers, screen } = req;
    const userAgent = headers['user-agent'];
    const screenWidth = screen.width;
    const screenHeight = screen.height;

    // 创建一个哈希值作为设备指纹
    const fingerprint = crypto.createHash('sha256')
        .update(userAgent + screenWidth + screenHeight)
        .digest('hex');

    return fingerprint;
}

app.post('/login', (req, res) => {
    const fingerprint = getDeviceFingerprint(req);
    console.log(`Device Fingerprint: ${fingerprint}`);
    res.send({ fingerprint });
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

方法二:使用Cookie或LocalStorage

虽然这种方法不如设备指纹精确,但它可以用于基本的唯一性识别。

示例代码:

// Node.js服务器端
app.post('/login', (req, res) => {
    const fingerprint = req.cookies.fingerprint || crypto.randomBytes(16).toString('hex');
    res.cookie('fingerprint', fingerprint, { maxAge: 900000, httpOnly: true });
    console.log(`Fingerprint: ${fingerprint}`);
    res.send({ fingerprint });
});

// 客户端JavaScript
document.addEventListener("DOMContentLoaded", function() {
    fetch('/login')
        .then(response => response.json())
        .then(data => {
            console.log(`Client-side fingerprint: ${data.fingerprint}`);
            localStorage.setItem('fingerprint', data.fingerprint);
        });
});

总结

  • 设备指纹:更全面地捕捉用户的设备特性,生成一个更为独特的标识符。
  • Cookie/LocalStorage:简单但不够精确,适用于简单的唯一性识别需求。

选择哪种方法取决于你的具体应用场景和对唯一性的要求。

你可以运行一下arp -a或者看一眼这个https://github.com/bevry/getmac

[@yorkie](/user/yorkie) 非常感谢。我试试看

[@heixiaoshan](/user/heixiaoshan) getmac也仅限在客户端通过http传mac地址回去,没有办法直接通过分析socket获取的呢

[@yorkie](/user/yorkie) 我试了只能获得服务端的mac,无法获取到客户端的MAC。

[@yorkie](/user/yorkie) 有没有其他方案,其实获取的mac的目的就是为了区分客户端唯一性。

持续关注中,我也想知道怎么获取

[@jinqiule](/user/jinqiule) 试了网上说的很多方法只能获取到本地的。

[@heixiaoshan](/user/heixiaoshan) 换思路, 客户端mac除了activeX和扩展取不到, 而且就算客户放行兼杀软没做掉你让你取到, 也无法保证唯一性。

看来我白说啦,都说了只能获取LAN(局域网)的mac地址,广域网是不能获取的

.yokrie已经说的很清楚了 . 给你一个思路 .如果是你的"客户端"是浏览器的话. 你生成一个唯一的id,保存在cookie,localStorage或sessionStorage之类的地方 . 每次启动都读取一下id .然后干你想干的事 … …

[@yorkie](/user/yorkie) 回答的很详细很好

[@yorkie](/user/yorkie) 不好意思。哈哈。之前看的不是很仔细。

[@Emma0809](/user/Emma0809) socket还没去接触过呢。不过你说的这个ID不会因为每次重启电脑而改变吗?

[@heixiaoshan](/user/heixiaoshan) 如果客户端断开连接,然后再次连接,id是会改变的

[@Emma0809](/user/Emma0809) 那其实也达不到效果,目标就是为了识别客户端机器。

[@chrome10086](/user/chrome10086) 目的是确定某一个用户,打开多个界面会有多个用户,不能确定唯一性,有办法确定mac吗 ,或者内网的ip也可以。

这个是不是要自己写个C++的扩展了?

[@jinqiule](/user/jinqiule) 目的是为了确认客户端唯一性,换句话说就是确认客户是不是用这一台PC在登陆。

[@heixiaoshan](/user/heixiaoshan) 恩,解决没有 ,我也想知道,我那个 www.buluoquan.com 的“临时”登陆用户,如果是同一局域网内,只能登陆一个,如果另一个登陆就会把前一个挤掉。

[@heixiaoshan](/user/heixiaoshan) 我不敢说是正确的啊,C++里面是可以获取到MAC地址的,然后通过这个C++的扩展,把MAC地址传给node

[@jinqiule](/user/jinqiule) 没有呢、没找到好的方案

说明问题要准确,你在寻找的是浏览器唯一性的解决方案

你可以在Google里搜索:browser fingerprint js,有很多现成的JS库。例如,fingerprintjs

工作原理就是根据每个浏览器的UA字符串、屏幕、语言、安装的插件等信息,计算出当前浏览器的一个唯一的hash值。根据这份报告,准确度达到94%。

这种方法不用在浏览器端存储任何信息,每次需要识别浏览器时,都是实时计算这个hash值。

为了提高准确度,你可以结合在cookie或者localStorage中存储唯一标识的方法,提高识别度。

不知道楼主找到好的解决方案没有,我这里也需要做客户端电脑登陆的判断,如果找到了好的解决方案 就共享下呗

在Node.js中直接获取客户端的MAC地址并不容易,因为浏览器的安全限制不允许JavaScript访问这样的低级别信息。但是,你可以通过一些间接的方法来实现客户端唯一性的识别,例如使用cookie、localStorage或后端生成的唯一标识符。

方法1: 使用Cookie

服务器可以发送一个唯一的cookie到客户端,每次请求时都可以从HTTP头部读取这个cookie的值。

// 服务器端(使用express)
const express = require('express');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.cookieParser());

app.get('/', (req, res) => {
    if (!req.cookies.uniqueId) {
        // 如果没有cookie,则创建并设置
        const uniqueId = generateUniqueId(); // 自定义函数,用于生成唯一ID
        res.cookie('uniqueId', uniqueId);
    }
    res.send(`Your unique ID is: ${req.cookies.uniqueId}`);
});

function generateUniqueId() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

app.listen(3000, () => console.log('Server running on port 3000'));

方法2: 使用localStorage

在客户端,可以通过JavaScript设置localStorage,并在后续请求中将其发送到服务器。

// 客户端(浏览器)
if (!localStorage.getItem('clientUniqueId')) {
    localStorage.setItem('clientUniqueId', generateUniqueId()); // 生成唯一ID
}
console.log("Your client unique ID is: " + localStorage.getItem('clientUniqueId'));

// 发送此ID到服务器
fetch('/set-client-id', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ clientId: localStorage.getItem('clientUniqueId') })
});

在服务器端接收这个ID:

// 服务器端
app.post('/set-client-id', (req, res) => {
    const clientId = req.body.clientId;
    console.log(`Received client ID: ${clientId}`);
    // 这里可以将ID保存到数据库或其他持久化存储中
    res.send('Client ID received');
});

这两种方法虽然不能直接获取MAC地址,但能有效地区分不同客户端的唯一性。

回到顶部