public ip npm package not working in Digital Ocean server - node.js

I have used the public-ip npm package to get the public IP address of the user, it is giving the same public IP address as in http://whatismyipaddress.com, but when using it in a Digital Ocean server it is giving me the Digital Ocean IP address instead of user's public IP address.
I have tried it on nodejs.
const publicIp = require('public-ip');
const ip = await publicIp.v4(); //to save ip in user
I want the public IP address of the user instead of getting the Digital Ocean IP address.

Just query https://api.ipify.org/
// web
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.ipify.org');
xhr.send();
xhr.onload = function() {
if (xhr.status != 200) {
console.log(`Error ${xhr.status}: ${xhr.statusText}`); // e.g. 404: Not Found
} else { // show the result
console.log(xhr.response)
}
};
// nodejs
const https = require('https');
https.get('https://api.ipify.org', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
console.log(JSON.parse(data));
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});

This function publicIp.v4() and public-ip module will help you get (detect) your public IP of server or computer that application's running on (not IP of user). And Digital Ocean returns value of its public IP is right.
In your case, you need to retrieve user's IP from user's request, it can be call remote client IP address. It's better for you to check this question Express.js: how to get remote client address
Hope it can help.

Related

Q: Hot to change Ip in request using tor-request npm

i'm trying to change Ip by using tor
According to Tor-Request Documentation I should be able to do this simply by using
newTorSession
But ip not changing. What is wrong in my code?
var tr = require('tor-request');
requestIP();
tr.setTorAddress('localhost', 9050);
tr.newTorSession( (err) =>
{
console.log (err);
requestIP();
return;
});
//console.log (tr.TorControlPort)
function requestIP() {
tr.request('https://api.ipify.org', function (err, res, body) {
if (!err && res.statusCode == 200) {
console.log("Your public (through Tor) IP is: " + body);
}
})
}
From the doc
You need to enable the Tor ControlPort if you want to programmatically
refresh the Tor session (i.e., get a new proxy IP address) without
restarting your Tor client.
so you need to follow these steps to enable ControlPort then pass that password to tor-request
tr.TorControlPort.password = 'PASSWORD'

Node https request options within response callback

I'm making an https request with the node https module wherein I set the localAddress option. Each local IP in the list is mapped to a different public IP.
I'm simply trying to print the public IP as reported by a server on the internet beside the corresponding local IP. The problem is I'm not sure how to get the request options in the response callback:
var https = require('https');
var localIps = [
'192.168.88.135',
'192.168.88.136',
'192.168.88.137',
'192.168.88.138',
'192.168.88.139',
];
for(index in localIps) {
var localIp = localIps[index];
var options = {
localAddress: localIp,
host: 'mypublicserver.com',
path: '/whats-my-ip.php'
};
https.get(options, function(res) {
res.on('data', function(d) {
console.log(
// XXX localIp is always printing the last IP from localIps
'Local Network IP: ' + localIp +
' Public Outbound IP: ' + d);
});
}).on('error', function(e) {
console.error(e);
});
}
It's printing something like this (which is wrong)
Local Network IP: 192.168.88.139 Public Outbound IP: 88.88.888.132
Local Network IP: 192.168.88.139 Public Outbound IP: 88.88.888.131
Local Network IP: 192.168.88.139 Public Outbound IP: 88.88.888.130
Local Network IP: 192.168.88.139 Public Outbound IP: 88.88.888.133
Local Network IP: 192.168.88.139 Public Outbound IP: 88.88.888.134
So how do I get the correct options object inside the response callback?
Apparently res is an http.IncomingMessage instance, but I'm failing to find how to get the associated request object from it.
The problem is that the for loop will finish iterating over localIps before any of the responses comes back. So when the first response comes back the localIp variable is set to last ip of the localIps array.
The easiest you can do is to enclose the code in closure or also called IIFE -> Immediately invoked function expression
var https = require('https');
var localIps = [
'192.168.88.135',
'192.168.88.136',
'192.168.88.137',
'192.168.88.138',
'192.168.88.139',
];
for(index in localIps) {
var localIp = localIps[index];
var options = {
localAddress: localIp,
host: 'mypublicserver.com',
path: '/whats-my-ip.php'
};
(function(opts){
https.get(opts, function(res) {
res.on('data', function(d) {
console.log(
// XXX localIp is always printing the last IP from localIps
'Local Network IP: ' + opts.localAddress +
' Public Outbound IP: ' + d);
});
}).on('error', function(e) {
console.error(e);
});
})(options);
}
To find more https://www.google.cz/search?q=javascript+for+loop+closure

nodejs - know from which ip address the server makes the get

Sorry, I'm quite new to network programming and nodejs. I'm using nodes in a server with some clients in a local network.
Sometimes I have to ask data to clients via get request:
// somewhere inside server.js
function askDataToClient(ip) {
var options = {
host: String(ip),
port: 80,
path: '/client/read',
auth: 'username:password'
};
var request = http.get(options, function(htres){
var body = "";
htres.on('data', function(data) {
body += data;
});
htres.on('end', function() {
body = JSON.parse(body);
res.json(body);
res.end();
})
htres.on('error', function(e) {
// ...
});
});
}
I'd like to know the server ip used for calling this get request.
I know of this answer but it gives me all the various network active on the server machine:
lo0 127.0.0.1
en1 192.168.3.60
bridge0 192.168.2.1
If I'm querying the client 192.168.3.36 I know it is the second ip, 192.168.3.60 because they are on the same network.. but How to know it programmatically?
You should be able to use htres.socket.address().address to get the IP.
Check out request.connection.remoteAddress property available for the HTTP Request object. This indicates the address of the remote host performing the request.

Node.js - How to get my external IP address in node.js app?

I'm using node.js and I need to get my external IP address, provided by my ISP.
Is there a way to achieve this without using a service like http://myexternalip.com/raw ?
Thanks.
Can do the same as what they do in Python to get external IP, connect to some website and get your details from the socket connection:
const net = require('net');
const client = net.connect({port: 80, host:"google.com"}, () => {
console.log('MyIP='+client.localAddress);
console.log('MyPORT='+client.localPort);
});
*Unfortunately cannot find the original Python Example anymore as reference..
Update 2019:
Using built-in http library and public API from https://whatismyipaddress.com/api
const http = require('http');
var options = {
host: 'ipv4bot.whatismyipaddress.com',
port: 80,
path: '/'
};
http.get(options, function(res) {
console.log("status: " + res.statusCode);
res.on("data", function(chunk) {
console.log("BODY: " + chunk);
});
}).on('error', function(e) {
console.log("error: " + e.message);
});
Tested with Node.js v0.10.48 on Amazon AWS server
--
Update 2021
ipv4bot is closed, here is another public API:
var http = require('http');
http.get({'host': 'api.ipify.org', 'port': 80, 'path': '/'}, function(resp) {
resp.on('data', function(ip) {
console.log("My public IP address is: " + ip);
});
});
--
Update 2022
ChatGPT wrote longer example using ipify with json: *Yes, i've tested it.
https://gist.github.com/unitycoder/745a58d562180994a3025afcb84c1753
More info https://www.ipify.org/
npm install --save public-ip from here.
Then
publicIp.v4().then(ip => {
console.log("your public ip address", ip);
});
And if you want the local machine ip you can use this.
var ip = require("ip");
var a = ip.address();
console.log("private ip address", a);
Use my externalip package on GitHub
externalip(function (err, ip) {
console.log(ip); // => 8.8.8.8
});
Edit: This was written back in 2013... The site is gone. I'm leaving the example request code for now unless anyone complains but go for the accepted answer.
http://fugal.net/ip.cgi was similar to that one.
or you can
require('http').request({
hostname: 'fugal.net',
path: '/ip.cgi',
agent: false
}, function(res) {
if(res.statusCode != 200) {
throw new Error('non-OK status: ' + res.statusCode);
}
res.setEncoding('utf-8');
var ipAddress = '';
res.on('data', function(chunk) { ipAddress += chunk; });
res.on('end', function() {
// ipAddress contains the external IP address
});
}).on('error', function(err) {
throw err;
}).end();
Ref: http://www.nodejs.org/api/http.html#http_http_request_options_callback
this should work well without any external dependencies (with the exception of ipify.org):
var https = require('https');
var callback = function(err, ip){
if(err){
return console.log(err);
}
console.log('Our public IP is', ip);
// do something here with the IP address
};
https.get({
host: 'api.ipify.org',
}, function(response) {
var ip = '';
response.on('data', function(d) {
ip += d;
});
response.on('end', function() {
if(ip){
callback(null, ip);
} else {
callback('could not get public ip address :(');
}
});
});
You could also use https://httpbin.org
GET https://httpbin.org/ip
Simply use superagent
var superagent = require('superagent');
var getip = function () {
superagent
.get('http://ip.cn/')
.set('User-Agent', 'curl/7.37.1')
.end(function (err, res) {
if (err) {
console.log(err);
}
var ip = res.text.match(/\d+\.\d+\.\d+\.\d+/)[0];
console.log(ip)
// Here is the result
});
};
Another little node module is ext-ip. The difference is, that you can use different response options, matching your coding style. It's ready to use out of the box ...
Promise
let extIP = require('ext-ip')();
extIP.get().then(ip => {
console.log(ip);
})
.catch(err => {
console.error(err);
});
Events
let extIP = require('ext-ip')();
extIP.on("ip", ip => {
console.log(ip);
});
extIP.on("err", err => {
console.error(err);
});
extIP();
Callback
let extIP = require('ext-ip')();
extIP((err, ip) => {
if( err ){
throw err;
}
console.log(ip);
});
The simplest answer, based on experience is that you can't get your external IP in most cases without using an external service, since you'll typically be behind a NAT or shielded by a firewall. I say in most cases, since there may be situations where you can get it from your router, but it is too case specific to provide a general answer.
What you want is simply to choose your favourite http client in NodeJS and find a maintained server that simply responds with the IP address in the body. You can also use a package, but you should see if it is still using a maintained remote server.
While there are plenty of examples already, here is one that first tries IPv6 and then falls back to IPv4. It leverages axios, since that is what I am comfortable with. Also, unless the optional parameter debug is set to true, the result is either a value or undefined.
const axios = require('axios');
// replace these URLs with whatever is good for you
const remoteIPv4Url = 'http://ipv4bot.whatismyipaddress.com/';
const remoteIPv6Url = 'http://ipv6bot.whatismyipaddress.com/';
// Try getting an external IPv4 address.
async function getExternalIPv4(debug = false) {
try {
const response = await axios.get(remoteIPv4Url);
if (response && response.data) {
return response.data;
}
} catch (error) {
if (debug) {
console.log(error);
}
}
return undefined;
}
// Try getting an external IPv6 address.
async function getExternalIPv6(debug = false) {
try {
const response = await axios.get(remoteIPv6Url);
if (response && response.data) {
return response.data;
}
} catch (error) {
if (debug) {
console.log(error);
}
}
return undefined;
}
async function getExternalIP(debug = false) {
let address;
// Try IPv6 and then IPv4
address = await getExternalIPv6(debug);
if (!address) {
address = await getExternalIPv4(debug);
}
return address;
}
module.exports { getExternalIP, getExternalIPv4, getExternalIPv6 }
Feel free to suggest improvements.
You may use the request-ip package:
const requestIp = require('request-ip');
// inside middleware handler
const ipMiddleware = function(req, res, next) {
const clientIp = requestIp.getClientIp(req);
next();
};
My shameless plug: canihazip (Disclosure: I'm the author of module, but not of the main page.)
It can be required as a module, exposing a single function that can optionally be passed a callback function an it will return a promise.
It can be also be installed globally and used as CLI.
You could very easily use an api solution for retrieving the external IP!
I made a ip tracker site made for this kinda thing a few days ago!
Here is a snippit of code you could use to get IP!
async function getIp(cb) {
let output = null;
let promise = new Promise(resolve => {
let http = new XMLHttpRequest();
http.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
output = this.responseText;
resolve("done");
}
}
http.open("GET", "https://iptrackerz.herokuapp.com/ip", true);
http.send();
});
await promise;
if (cb != undefined) {
cb(JSON.parse(output)["ip"]);
} else {
return JSON.parse(output)["ip"];
}
}
Ok, now you have the function getIp()!
The way I coded it allows you to do 2 different ways of invoking it!
Here they are.
Asynchronous
async function printIP() {
let ip = await getIp();
document.write("Your IP is " + ip);
};
printIP();
Callback
getIp(ip => {
document.write("Your IP is " + ip);
});
I was looking for a solution not relying to other's libraries/ resources,
and found this as acceptable alternative:
Just a GET request to external server ( under my control ),
where I read req.headers['x-forwarded-for'] and serve it back to my client.
node.js has a lot of great built in modules you can use without including any external dependencies. you can make this file.
WhatsMyIpAddress.js
const http = require('http');
function WhatsMyIpAddress(callback) {
const options = {
host: 'ipv4bot.whatismyipaddress.com',
port: 80,
path: '/'
};
http.get(options, res => {
res.setEncoding('utf8');
res.on("data", chunk => callback(chunk, null));
}).on('error', err => callback(null, err.message));
}
module.exports = WhatsMyIpAddress;
Then call it in your main.js like this.
main.js
const WhatsMyIpAddress = require('./src/WhatsMyIpAddress');
WhatsMyIpAddress((data,err) => {
console.log('results:', data, err);
});
You can use nurl library command ippublic to get this. (disclosure: I made nurl)
> npm install nurl-cli -g
> ippublic;
// 50.240.33.6

how to get external ip of the server from node.js

I'm using now.js and there's this line that refers to localhost. In order for someone to access the server outside I need to modify localhost to be the current external ip of my computer(my ip is dynamic). Is there any way to detect the current external ip from the script?
window.now = nowInitialize("//localhost:8081", {});
You could ask an external service like this one (which is nice because it returns it without formatting).
To use it, you could use Node's built in http module:
require('http').request({
hostname: 'fugal.org',
path: '/ip.cgi',
agent: false
}, function(res) {
if(res.statusCode != 200) {
throw new Error('non-OK status: ' + res.statusCode);
}
res.setEncoding('utf-8');
var ipAddress = '';
res.on('data', function(chunk) { ipAddress += chunk; });
res.on('end', function() {
// ipAddress contains the external IP address
});
}).on('error', function(err) {
throw err;
});
Keep in mind that external services can go down or change — this has happened once already, invalidating this answer. I've updated it, but this could happen again…

Resources