|
|
@@ -40,13 +40,67 @@ export const generateCaptcha = () => {
|
|
|
return res;
|
|
|
};
|
|
|
|
|
|
-//3:------------ 获取请求者ip 用来确定验证码是否正确
|
|
|
+// 生成电脑唯一id
|
|
|
+import crypto from 'crypto';
|
|
|
+
|
|
|
+export const dianNaoId = (req: any) => {
|
|
|
+ // 1. 首先使用原有逻辑获取IP地址
|
|
|
+ let clientIp = req.ip; // 如果使用了 Express 等框架,有时可以直接这样获取
|
|
|
+
|
|
|
+ // 优先从常见的代理头信息中获取
|
|
|
+ const forwardedHeader = req.headers['x-forwarded-for'];
|
|
|
+ const realIpHeader = req.headers['x-real-ip'];
|
|
|
+
|
|
|
+ if (forwardedHeader) {
|
|
|
+ // X-Forwarded-For 格式为 "client, proxy1, proxy2",第一个 IP 是真实客户端 IP
|
|
|
+ clientIp = forwardedHeader.split(',')[0].trim();
|
|
|
+ } else if (realIpHeader) {
|
|
|
+ // X-Real-IP 通常直接包含客户端的真实 IP
|
|
|
+ clientIp = realIpHeader;
|
|
|
+ } else {
|
|
|
+ // 如果没有代理头信息,则回退到连接信息(通常只在直接访问时有效)
|
|
|
+ let rawIp = req.socket.remoteAddress || req.connection.remoteAddress;
|
|
|
+ // 处理 IPv6 格式(如 "::ffff:192.168.1.1")
|
|
|
+ clientIp = rawIp && rawIp.replace(/^.*:/, '');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 收集其他可以区分设备的请求头信息
|
|
|
+ const userAgent = req.headers['user-agent'] || 'unknown';
|
|
|
+ const acceptLanguage = req.headers['accept-language'] || 'unknown';
|
|
|
+ const acceptEncoding = req.headers['accept-encoding'] || 'unknown';
|
|
|
+ const secCHUA = req.headers['sec-ch-ua'] || ''; // 客户端提示(较新的浏览器支持)
|
|
|
+ const secCHUAPlatform = req.headers['sec-ch-ua-platform'] || '';
|
|
|
+
|
|
|
+ // 3. 组合所有信息生成一个复合字符串
|
|
|
+ const compositeString = `${clientIp}-${userAgent}-${acceptLanguage}-${acceptEncoding}-${secCHUA}-${secCHUAPlatform}`;
|
|
|
+
|
|
|
+ // 4. 使用SHA-256哈希生成固定长度的设备指纹(更安全,冲突概率低)
|
|
|
+ const deviceFingerprint = crypto.createHash('sha256').update(compositeString).digest('hex');
|
|
|
+
|
|
|
+ return deviceFingerprint;
|
|
|
+};
|
|
|
+
|
|
|
+//3:------------ 获取请求者ip
|
|
|
export const ipLocResFu = (req: any) => {
|
|
|
- // 获取IP,并处理可能的IPv6格式
|
|
|
- let rawIp = req.socket.remoteAddress;
|
|
|
- // 简单的处理,如果包含`::ffff:`则去除,否则直接使用
|
|
|
- const clientIp = rawIp && rawIp.replace(/^.*:/, '');
|
|
|
- // console.log('客户端IP:', clientIp);
|
|
|
+ let clientIp = req.ip; // 如果使用了 Express 等框架,有时可以直接这样获取
|
|
|
+
|
|
|
+ // 优先从常见的代理头信息中获取
|
|
|
+ const forwardedHeader = req.headers['x-forwarded-for'];
|
|
|
+ const realIpHeader = req.headers['x-real-ip'];
|
|
|
+
|
|
|
+ if (forwardedHeader) {
|
|
|
+ // X-Forwarded-For 格式为 "client, proxy1, proxy2",第一个 IP 是真实客户端 IP[6,7](@ref)
|
|
|
+ clientIp = forwardedHeader.split(',')[0].trim();
|
|
|
+ } else if (realIpHeader) {
|
|
|
+ // X-Real-IP 通常直接包含客户端的真实 IP[1,3](@ref)
|
|
|
+ clientIp = realIpHeader;
|
|
|
+ } else {
|
|
|
+ // 如果没有代理头信息,则回退到连接信息(通常只在直接访问时有效)
|
|
|
+ let rawIp = req.socket.remoteAddress || req.connection.remoteAddress;
|
|
|
+ // 处理 IPv6 格式(如 "::ffff:192.168.1.1")[2](@ref)
|
|
|
+ clientIp = rawIp && rawIp.replace(/^.*:/, '');
|
|
|
+ }
|
|
|
+
|
|
|
return clientIp;
|
|
|
};
|
|
|
|