52 lines
1.5 KiB
TypeScript
52 lines
1.5 KiB
TypeScript
import { Request, Response, NextFunction } from 'express';
|
|
|
|
export const ipDetectionMiddleware = (req: Request, res: Response, next: NextFunction) => {
|
|
// Extrair o endereço IP real
|
|
req.realIP = determineRealIP(req);
|
|
|
|
// Registrar a detecção para debug
|
|
console.log(`Requisição de ${req.realIP} (original: ${req.ip})`);
|
|
|
|
next();
|
|
};
|
|
|
|
function determineRealIP(req: Request): string {
|
|
// Array de possíveis fontes de IP, em ordem de preferência
|
|
const ipSources = [
|
|
req.headers['x-forwarded-for'],
|
|
req.headers['x-real-ip'],
|
|
req.headers['cf-connecting-ip'],
|
|
req.ip,
|
|
req.socket?.remoteAddress
|
|
];
|
|
|
|
// Filtrar valores nulos e processar x-forwarded-for que pode conter múltiplos IPs
|
|
for (const source of ipSources) {
|
|
if (source) {
|
|
// x-forwarded-for pode ter múltiplos IPs separados por vírgula
|
|
if (typeof source === 'string' && source.includes(',')) {
|
|
const firstIP = source.split(',')[0].trim();
|
|
if (firstIP && isValidIP(firstIP)) return firstIP;
|
|
} else if (isValidIP(source as string)) {
|
|
return source as string;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fallback para um valor padrão se nenhum IP válido for encontrado
|
|
return '0.0.0.0';
|
|
}
|
|
|
|
function isValidIP(ip: string): boolean {
|
|
// Função simples para verificar se uma string parece um IP válido
|
|
return !!ip && ip !== 'unknown' && ip !== '::1' && ip !== 'localhost';
|
|
}
|
|
|
|
// Estender a interface Request para incluir a propriedade realIP
|
|
declare global {
|
|
namespace Express {
|
|
interface Request {
|
|
realIP: string;
|
|
}
|
|
}
|
|
} |