How can I get the client IP address with socket.io? - node.js

I've searched the whole SO but I couldn't find my answer. I want to get client IP address with socket io. v2.0.3
app.js
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
/// other imports ...
//with or without this line nothing changes
io.set('transports', ['websocket']);
app.use(function(req, res, next) {
req.db = db;
next();
});
require('./sockets')(io, db);
sockets.js
module.exports = function(io, db) {
io.on('connection', function(socket) {
var ip = socket.request.socket.remoteAddress ; // undefined
//var ip = socket.handshake.headers["x-forwarded-for"]; undefined
//var ip = socket.handshake.headers["X-Forwarded-For"]; undefined
});
});
so this code does not work:
var ip = socket.request.socket.remoteAddress
this one does not work eather:
var ip = socket.handshake.headers["x-forwarded-for"];
//var ip = socket.handshake.headers["X-Forwarded-For"];
with this nginx config:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
is there anyway to get the client IP address with socket.io?

I changed nginx config and the problem solved:
server {
listen 80;
server_name example.com;
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Real-IP;
real_ip_recursive on;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
}
}
and in sockets.js
module.exports = function(io, db) {
io.on('connection', function(socket) {
var ip = socket.handshake.headers["x-real-ip"];
});
});

You can try socket.handshake.address or socket.handshake.address.substr(7)

Related

Using Nginx as proxy for Node.js' Express and Socket.io

I want to run an express server and a socket.io server on an node.js instance which are reachable through nginx. If possible, I would favor to run them both on the same port, but I did not reach that goal either.
I can reach the webserver locally and from extern.
I can only reach the socket server locally.
When I call the page, my browsers log shows the following error:
GET https://example.com/socket.io/?EIO=3&transport=polling&t=O6qCW5Y
400 Bad Request
So I think the problem lies somewhere in the nginx config.
My app.js code for the socket.io server:
const http = require('http').createServer();
const io = require('socket.io')(http);
http.listen(3001, () => {
console.log('Socket-Server listening on port: 3001');
});
io.on('connection', (socket) => {
...
});
My code for the client:
window.onload = function() {
const socket = io.connect('https://box-api.com/');
socket.on('connect', () => {
...
}
}
My nginx config:
server {
server_name example.com;
root /nodejs/example.com;
include static_files.conf;
index app.js;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
}
location /socket.io {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Certbot stuff
...
}

I'm using nginx to put my nodejs and socket.io signaler server online, I don't know why but only users who are on the same network can communicate

I'm using nginx on linux to put my nodejs and socket.io signaler server online, I don't know why but only users who are on the same network can communicate on socket.io, how can i configure nginx and socket.io server to allow communication between users outside the network ?
Here is my nginx and socket.io server configuration:
1) /etc/nginx/conf.d/app.com.conf
server {
listen 80;
listen [::]:80;
server_name 5902483.lovecames.com;
root /usr/share/nginx/html;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name 5902483.lovecames.com;
root /usr/share/nginx/html;
ssl_certificate /...;
ssl_certificate_key /...;
ssl_session_timeout ...;
ssl_session_cache ...;
ssl_session_tickets off;
# intermediate configuration
ssl_protocols ...;
ssl_ciphers ...
ssl_prefer_server_ciphers off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
resolver 0.0.0.0;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~* \.io {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy false;
proxy_pass http://localhost:8080;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location ~* / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
2) /etc/nginx/nginx.conf
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
3) nodejs server:
var fs = require('fs');
var _static = require('node-static');
var file = new _static.Server('./static', {
cache: false
});
var app = require('http').createServer(serverCallback);
function serverCallback(request, response) {
request.addListener('end', function () {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
response.setHeader('Access-Control-Allow-Headers', 'Content-Type');
file.serve(request, response);
}).resume();
}
var io = require('socket.io').listen(app, {
// log: true,
origins: '*:*'
});
io.set('transports', [
//'websocket',
'xhr-polling',
'jsonp-polling'
]);
var channels = {};
var users = [];
io.sockets.on('connection', function (socket) {
var initiatorChannel = '';
if (!io.isConnected) {
io.isConnected = true;
}
socket.on('new-channel', function (data) {
if (!channels[data.channel]) {
initiatorChannel = data.channel;
}
channels[data.channel] = data.channel;
onNewNamespace(data.channel, data.sender);
});
socket.on('presence', function (channel) {
var isChannelPresent = !! channels[channel];
socket.emit('presence', isChannelPresent);
});
socket.on('disconnect', function (channel) {
if (initiatorChannel) {
delete channels[initiatorChannel];
}
});
});
function onNewNamespace(channel, sender) {
io.of('/' + channel).on('connection', function (socket) {
var username;
if (io.isConnected) {
io.isConnected = false;
socket.emit('connect', true);
socket.emit('user-video-stream', JSON.stringify(users));
}
socket.on('message', function (data) {
if (data.sender == sender) {
if(!username) username = data.data.sender;
socket.broadcast.emit('message', data.data);
}
});
socket.on('disconnect', function() {
if(username) {
socket.broadcast.emit('user-left', username);
username = null;
}
});
});
}
function isInArray(users,newUser) {
found = false;
users.forEach(function(element) {
if(element.videoId == newUser.videoId) found = true;
}, this);
return found;
}
app.listen(8080, '0.0.0.0', function(){
console.log('listening on *:8080');
});
4) client-side:
var SIGNALING_SERVER = 'https://5902483.lovecames.com/';

CORS issues with Express, Socket.io and Nginx

I have adapted a tutorial to get a simple Socket.io chat going in Node. It works when hosted locally, but after pushing it to a test server I can't get the socket connection to be accepted. Seems to be a cross-origin related matter, though I'm slightly confused about how to route things in Nginx also. Following the advice in the related questions hasn't helped.
Client script:
var socket = io.connect('http://localhost/socket.io');
Index.js:
const express = require('express');
const app = express();
const path = require('path');
const httpServer = require('http').createServer(app);
const io = require('socket.io')(httpServer, {
cors:true,
origins:["*"],
// origins:["http://xxx.xxx.xxx.xxx:8080"],
// transports: ['websocket'],
});
const views_path = (__dirname + '/views');
app.set('views',views_path);
app.use(express.static(__dirname + '/public'));
app.get('/', function(req,res){
console.log('render request received');
res.render('startPage.ejs');
});
io.sockets.on('connection', socket => {
console.log('connection received.')
socket.on('username', function(username) {
socket.username = username;
io.emit('is_online', socket.username);
});
//...
});
httpServer.listen(8080);
nginx sites-available:
server {
server_name campfire;
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/campfire/html;
index index.html index.htm index.nginx-debian.html;
location ^~ /assets/ {
gzip_static on;
expires 12h;
add_header Cache-Control public;
}
location / {
proxy_set_header Host $host;
#proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8080;
}
location /socket.io/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'Upgrade';
proxy_http_version 1.1;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:8080/socket.io/;
}
}
Any insights welcome!
Hope this will help with all the CORS error
Because it will handle it for you
const cors = require('cors');
app.use(cors());
Docs CORS
Making this change fixed the issue:
Client script: var socket = io.connect();
This way uses the default connection destination with socket.

Cannot GET / Node JS Amazon EC2 server issues

In my app.js file
app.listen(process.env.PORT || 8080, () => console.log(`Listening on port ${process.env.PORT || 8080}!`));
In my webpack.config.js file
devServer: {
port: 3000,
open: true,
proxy: {
'/api': 'http://localhost:8080'
}
}
In /etc/nginx/sites-enabled/default on my EC2 instance
server {
listen 80;
server_name _;
location / {
proxy_pass http://[private ip]:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
EDIT: Full app.js file
const app = express();
app.use(cors());
app.use(express.static('dist'));
app.listen(process.env.PORT || 8080, () => console.log(`Listening on port ${process.env.PORT || 8080}!`));
app.post('/api/[route]', async (req, res, next) => {
try {
const seq = await sequelize();
const file = await [...];
} catch (err) {
return next(err);
}
});
The correct config was
server {
listen 80;
server_name _;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
I believe i had installed pm2 incorrectly at the beginning, because both the nginx server and pm2 were trying to listen on port 80. So i did a fresh install of everything, and voila it works now.

Deploy Nginx, Socket IO, Linode 404 error

I have been struggling trying to deploy a NodeJS server as SocketIO server on Linode. I have deployed my Django projects that works fine and I have redirected a subdomain to talk to the node server listening on port 8002 of local host.
I get a 404 error in my nginx log.
"GET /socket.io/?EIO=3&transport=polling HTTP/1.1" 404 72 "-" "Dalvik/2.1.0 (Linux; U; Android 5.0.1; LG-D850 Build/LRX21Y)"
Here is my nginx config
server {
listen 80;
server_name www.domain.com;
location / {
proxy_pass http://127.0.0.1:8000;
}
location /static {
alias /home/exampledir/staticfiles;
}
access_log /home/exampledir/nginx-access.log;
error_log /home/exampledir/nginx-error.log info;
}
server {
listen 80;
server subdomain.domain.com;
location / {
proxy_pass http://127.0.0.1:8002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
Here is my nodejs server file
var socket = require('socket.io');
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
server.listen(8002, '127.0.0.1');
var io = socket.listen(server);
var redis = require('redis');
var sub = redis.createClient();
sub.subscribe('notify');
io.on('connection', function(socket){
socket.on('join', function (data) {
...
});
});
//Grab message from Redis and send to client
sub.on('message', function(channel, message){
...
});
I have tried using CORS and stuff but it does not work just keeps giving me a 404. I have verified the node server is running at 127.0.0.1:8002
My android socket is connecting to
mSocket = IO.socket("http://subdomain.domain.com/);
Please help.
Try this config
server {
listen 80;
# Make site accessible from http://localhost/
server_name domain.com;
location / {
proxy_pass http://127.0.0.1:8000;
}
location / {
proxy_pass http://127.0.0.1:8000;
}
location /static {
alias /home/example-dir/staticfiles;
}
access_log /home/example-dir/nginx-access.log;
error_log /home/example-dir/nginx-error.log info;
}
server {
listen 80;
server_name subdomain.domain.com;
location / {
proxy_pass http://127.0.0.1:8002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
access_log /home/example-dir/socketnginx-access.log;
error_log /home/example-dir/socketnginx-error.log info;
}

Resources