After upgrading socket.io from 1.x.x to 2.0.3 I can't get client's IP address — it's always undefined
.
Test environment:
Ubuntu 14.04.5 LTS
Node.js 8.1.2
Socket.io 2.0.3
Server:
require('socket.io')(8888).on('connection', socket => {
console.log('socket.client.conn.remoteAddress', socket.client.conn.remoteAddress);
console.log('socket.request.connection.remoteAddress', socket.request.connection.remoteAddress);
console.log('socket.handshake.address', socket.handshake.address);
});
Client:
<script src="http://192.168.13.13:8888/socket.io/socket.io.js"></script>
<script>
var socket = io('http://192.168.13.13:8888', { transports: [ 'websocket' ] });
socket.on('connect', function(){
console.log('connected');
});
</script>
Aaaaand it's gone.
daniil@ubuntu:/var/srv/node-test# node server.js
socket.client.conn.remoteAddress undefined
socket.request.connection.remoteAddress undefined
socket.handshake.address undefined
When I remove { transports: [ 'websocket' ] }
from client's code, I got this:
socket.client.conn.remoteAddress ::ffff:192.168.13.12
socket.request.connection.remoteAddress ::ffff:192.168.13.12
socket.handshake.address ::ffff:192.168.13.12
Socket.io 1.7.4 works fine. Socket.io >=2.0.1 is not.
@kirick13 I am experiencing the exact same behavior with { transports: [ 'websocket' ] }
We also experience this issue on 2.x and are unable to upgrade for now.
https://github.com/thelounge/lounge/pull/1143
https://travis-ci.org/thelounge/lounge/builds/241839980
Was this fixed? As i'm having the same issue.
@burstpay I think its still not fixed.
Here you have the solution to obtain remoteAddress in Socket.io 2.x
Same problem here, always undefined... major issue !
Could you please try with engine.io v3.1.3?
@darrachequesne How do you access that remoteAddress
in context of socket.io itself? socket.remoteAddress
is undefined in connect
callback.
Is it correct that it should be socket.request.connection.remoteAddress
?
@xPaw it should be socket.handshake.address
(ref)
Sorry, what is the proper way to upgrade my engine.io dependency from 3.1.0 to 3.1.3 ?
Can I edit the package.json from my socket.io 2.0.3 and how to refresh the dependency ?
I installed engine.io inside my own project and it's clean:)
npm install engine.io
Now "socket.handshake.address" work but I get an ipv4-mapped IPv6address. I must parse the string (or better, upgrade my log display to ipv6)
::ffff:127.0.0.
Issue close...
@Serveurperso You can also turn off IPv6 if you http.listen(port, '0.0.0.0')
. This way your server won't be IPv6-compatible, but also you will have remote addresses in IPv4 format. Given the fact you were going to convert IPv6 address to IPv4, IPv6 connectivity shouldn't be an issue for you.
io.on('connection', function(socket){
const address = socket.handshake.headers["x-forwarded-for"].split(",")[0];
console.log(address);
});
@Serveurperso You can also turn off IPv6 if you
http.listen(port, '0.0.0.0')
. This way your server won't be IPv6-compatible, but also you will have remote addresses in IPv4 format. Given the fact you were going to convert IPv6 address to IPv4, IPv6 connectivity shouldn't be an issue for you.
@polkovnikov-ph Thanks for this great solution. Is this option somewhere documented?
It was a long time ago, but I'm pretty sure I just made a google search with something like "http listen force ipv4" and opened first link that lead to stackoverflow.
The issue is not actually related to Node.js. It's platform-specific socket behavior. Listening on ::
meta-address might or might not listen also on 0.0.0.0
. The choice of ::
as default address in listen
call on IPv6-enabled systems was quite arbitrary and misleading though. This is why good API design generally implies functions take no default parameters (as enforced language-wide in Haskell and several other languages, for example).
Thanks for your prompt response.
socket Object SERVER SIDE !
const sha_last_index_colon = socket.handshake.address.lastIndexOf(':');
if (sha_last_index_colon > -1) {
if (socket.handshake.address.lastIndexOf('.') > -1) {
socket.this_is_a_demo = {
ipv4: socket.handshake.address.slice(sha_last_index_colon + 1),
ipv6: socket.handshake.address.slice(0, sha_last_index_colon)
}
} else {
socket.this_is_a_demo = {
ipv6: socket.handshake.address
}
}
} else {
socket.this_is_a_demo = {
ipv4: socket.handshake.address
}
}
console.log(socket.this_is_a_demo.ipv4);
console.log(socket.this_is_a_demo.ipv6);
Most helpful comment
@Serveurperso You can also turn off IPv6 if you
http.listen(port, '0.0.0.0')
. This way your server won't be IPv6-compatible, but also you will have remote addresses in IPv4 format. Given the fact you were going to convert IPv6 address to IPv4, IPv6 connectivity shouldn't be an issue for you.