Express.js req.ip đang trả về :: ffff: 127.0.0.1


98

Tôi hiện đang cố gắng lấy IP của người dùng được yêu cầu. Vấn đề là IP đang trở lại ::ffff:127.0.0.1thay vì 127.0.0.1. Tôi đã thử sử dụng trusted proxytùy chọn (mặc dù không sử dụng proxy) và tùy chọn req.ipsnày trống. Sử dụng 4.x Express.js.

router.get('/', function(req, res, next) {
    console.log('ip', req.ip)
    res.send({})
});

Vì vậy, những gì bạn đang sử dụng req.iphoặc req.ips?
Aleksandr M

req.ip, chỉ thử req.ipsnhư một thử nghiệm. Tôi chỉ không chắc chắn điều gì đang gây ra tiền tố ::ffff:.
rockerBOO


Vâng, đây là nó. Windows 7 có một lớp chuyển tiếp cho các yêu cầu IPv4 và thêm tiền tố này vào IP.
rockerBOO

Câu trả lời:


155

::ffff:là tiền tố mạng con cho địa chỉ IPv4 (32 bit) được đặt bên trong không gian IPv6 (128 bit). IPv6 được chia thành hai phần, tiền tố mạng con và hậu tố giao diện. Mỗi cái dài 64 bit, hoặc 4 nhóm gồm 4 ký tự thập lục phân.

Trong IPv6, bạn được phép xóa các số 0 ở đầu, sau đó xóa các số 0 liên tiếp, nghĩa là ::ffff:thực sự được dịch thành 0000:0000:ffff:0000, địa chỉ này đã được chỉ định là tiền tố mạng con IPv4 thành IPv6, vì vậy bất kỳ bộ xử lý IPv6 nào cũng hiểu nó đang hoạt động với địa chỉ IPv4 và xử lý nó cho phù hợp.

Trong tương lai gần, tất cả các địa chỉ IP sẽ là IPv6, điều này là do chúng ta đã gần hết số lượng (4,2 tỷ, trừ đi một số không gian cho các mục đích sai) trong không gian địa chỉ IPv4.

IPv6 cho phép một không gian lớn hơn nhiều. "340 undecillion phải là đủ cho bất kỳ ai" - Bill Gates phát biểu trên IPv6.

Điều quan trọng là bắt đầu định địa chỉ IP bằng cách sử dụng không gian tên IPv6 và do đó đưa ::ffff:vào mã của bạn vì trong tương lai sẽ có dữ liệu thập lục phân thực giữa các dấu hai chấm đó. Nếu bạn loại bỏ nó vì lý do thẩm mỹ, mã của bạn sẽ bị hỏng khi nó chuyển sang mạng IPv6 hoặc nó đối đầu với địa chỉ IPv6.

Một số mạng hiện đang chạy IPv6 và bạn sẽ sớm gặp phải các địa chỉ IP IPv6; tạo bước nhảy vọt ngay bây giờ hoặc có nguy cơ phá vỡ mã của bạn trong tương lai.

Phiên bản TL; DR (viết tắt) của vấn đề là: Mọi thứ đều hoạt động tốt. Đừng thay đổi nó, đó là phiên bản IPv6 của địa chỉ IPv4.

IPv6 IPv4

Nếu bạn muốn làm cho mã của mình tương thích với IPv6, tất cả những gì bạn phải làm là kiểm tra ::ffff:tiền tố ... nếu nó tồn tại, hãy xóa nó và xử lý phần còn lại dưới dạng IPv4 ... nếu ::ffff:không tồn tại, đó là địa chỉ IPv6 và cần được xử lý như vậy. Bạn có thể kiểm tra kỹ bằng cách xem các dấu chấm có trong chuỗi hay không, nếu có thì đó là IPv4.

Hãy ghi nhớ mọi thứ, trừ những điều chỉnh bạn cần thực hiện đối với địa chỉ IP, bạn chỉ đang ghi lại IP, phải không? Nó sẽ quan trọng đối với trình phân tích cú pháp và tổng hợp nhật ký để mong đợi ::ffff:127.0.0.1và tương tự như vậy trong tương lai. Trừ khi bạn cần thay đổi một IP, hãy để nó như những gì bạn nhận được.


Tuy nhiên, nghe có vẻ khá nguy hiểm khi kiểm tra ::ffff:tiền tố . Bạn biết đấy, một IPv6 có nhiều ký hiệu.
Константин Ван

1
Không, nó an toàn :) Có đề xuất, và sau đó có việc thực hiện. vi.wikipedia.org/wiki/… IETF đã nhận ra rằng các bộ định tuyến không thể ghi nhiều chu trình tìm kiếm địa chỉ IP như vậy, và ngoài ra, không ai giữ số không vì nó lãng phí không gian. Ý tưởng cho phép các số không chỉ là một ý tưởng. Vào năm 2019, nếu bạn gửi :: ffff: trong một gói mạng là 0000: 0000: ffff: 0000, mặc dù hợp lệ về mặt kỹ thuật đối với đề xuất ban đầu, nó không hợp lệ đối với đề xuất IETF hiện tại cũng như sẽ không được nhìn thấy trong hầu hết các bộ định tuyến tương thích IPv6.
Nick Steele

1
Vì vậy, tôi có thể chắc chắn rằng chúng luôn ở dạng chuẩn . Không biết mọi thứ diễn ra như thế nào trong tự nhiên. Cảm ơn.
Константин Ван

Điều này là phổ biến không may. Con người chỉ chú ý khi cần thiết. Ai đó phác thảo một cái gì đó, thiết kế ban đầu hỗ trợ rất nhiều tính năng, họ tạo ra một RFC, không ai thực sự chú ý đến nhiều phần của thiết kế, nó trở thành một tiêu chuẩn, sau đó khi thực hiện mọi người nhận thấy cần có những thay đổi lớn :) IPv6 hơi kỳ quặc bởi vì gọi nó là "cannonical" là một chút kỳ lạ. Họ có lẽ nên gọi nó là "1.1" hoặc một cái gì đó để mọi người có thể nhanh chóng hiểu những gì đang xảy ra, nhưng bởi vì các số không tùy chọn của bản nháp ban đầu khiến bạn tốn gấp 10 lần tính toán trong các bộ định tuyến nên nó chỉ đơn giản bị bỏ qua.
Nick Steele

29

Đây dường như là một điểm khác biệt của ipv6: đối với địa chỉ ipv4, ipv6 dường như kết hợp ký hiệu ipv6 với ký hiệu ipv4.

Để nhận được cả địa chỉ ipv4 và ipv6 trong ký hiệu đơn giản, không trộn lẫn, tôi đang sử dụng:

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
if (ip.substr(0, 7) == "::ffff:") {
  ip = ip.substr(7)
}


10

Windows 7 đã bật IPv6 theo mặc định. Mặc dù máy chủ của tôi chỉ lắng nghe trên IPv4, Windows 7 sẽ gửi ::ffff:tiền tố tới IPv4 như một phần của quá trình chuyển đổi sang IPv6

::ffff:0:0:0/96 - Tiền tố được sử dụng cho các địa chỉ được dịch IPv4 được sử dụng bởi giao thức Dịch IP / ICMP (SIIT) không trạng thái.

Chuyển đổi từ IPv4


8

Tôi đang gặp sự cố khi cố gắng so sánh các địa chỉ được ánh xạ ipv4 và thấy thư viện ipaddr.js hữu ích :-)

ví dụ

_.isEqual(ipaddr.process('::ffff:127.0.0.1'), ipaddr.process('127.0.0.1')) === true

3

Hãy thử cách này để lấy địa chỉ ip chính xác bằng cách xóa mạng con,

    let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
    ip = ip.toString().replace('::ffff:', '');

-2

Bạn có thể Lấy địa chỉ Ip của mình một mình hoặc với Họ được chỉ định bằng cách sử dụng ổ cắm

     var app = require('express')();

 app.get("/ip", (req, res) => {
        console.log(req.ip) 
       let ip = req.ip.split(':');
        let ip_details = req.socket.address();
          console.log(ip_details);                     
   // { address: '::ffff:127.0.0.1', family: 'IPv6', port: 3001 

           console.log(ip[3]);//127.0.0.1
                            res.json(ip[3]);  
      }

-2
var ip = req.ip.split(':').pop();

Như các câu trả lời khác giải thích, đây là địa chỉ IPv6. Xem câu trả lời của @Nick Steele ở trên. Bạn thực sự không muốn làm điều này.
Misha Nasledov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.