Can I get the client IP address in express js api? - node.js

I'm trying to make a chat app using node.js as backend, where every client has a specific IP so I need to get the IP of the client using my api.

You can use a middleware express-ip
const express = require('express');
const app = express();
const expressIp = require('express-ip');
app.use(expressIp().getIpInfoMiddleware);
app.get('/', function (req, res) {
console.log(req.ipInfo);
});

you can get the variable from req object req.connection.remoteAddress
app.get('/', function (req, res) {
console.log(req.connection.remoteAddress);
});

Related

Can I shutdown specific route in runtime in the express server?

I have an example
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('hello world');
});
In the runtime (for example in 10 sec), I want to stop handling my / endpoint, so when I will make a request, the response would be like Cannot GET /
How can I achieve this behaviour?
You need to create a flag that can be set based on when you want to keep preventing the route from providing the data. Instead of showing Cannot GET /, you should send the status code 503 status code i.e service unavailable.
var express = require('express');
var app = express();
app.get('/', function (req, res) {
if (flag) {
res.status(503).send('Service Unavailable');
} else {
res.send('hello world');
}
});
This could be great if you want to make it for a single route. When you want to control many routes, you can create middleware and use flag similar to the above one.

Protecting post routes NodeJS

I am working on a nodeJS application. So far i've learned you can protect routes with JWT and i've implemented this. The problem is, I am not sure how to protect a route where the user is allowed to post to.
Let's take a register route for example, this route will be used for user registration. I want users to be able to post to this, BUT only from my application. I dont want anyone to just be able to connect to it via postman and post whatever. How do you protect these kind of routes.
Thanks in advance.
You can use CORS middleware to allow only specific clients to access your server https://expressjs.com/en/resources/middleware/cors.html
Example:
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
origin: 'http://example.com',
}
app.get('/products/:id', cors(corsOptions), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for only example.com.'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})

Creating a Modular REST API in ExpressJS

I'm having some trouble creating a RESTful API in Node/Express. In the app I'm building, a user has many messages, and messages belong to users. I need to be able to make an HTTP requests to retrieve all messages by a particular user. Here's the basic structure of the app, starting with the basic server, which delegates routing to a file called 'config/middleware.js'.
//server.js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
require('./config/middleware.js')(app, express);
var port = process.env.PORT || 8080;
app.use(bodyParser.json());
app.use(express.static(__dirname + '/../client'));
app.listen(port);
This is the middleware file where we send requests to the appropriate router. A request made to 'users/5/messages' would get routed to the messages router, and a request made to 'users/5' would get routed to the users router.
// config/middleware.js
module.exports = function(app, express) {
var usersRouter = express.Router();
var messagesRouter = express.Router();
app.use('/users/:userId/messages', messagesRouter);
app.use('/users', usersRouter);
require('../routers/users')(usersRouter);
require('../routers/messages')(messagesRouter);
};
This is the messages router. If a get request is made to '/users/5/messages', I want the getAllMessages function to be run, which should return all messages by the user with userId 5.
// routers/messages.js
var messagesController = require('../controllers/messages');
module.exports = function(app) {
app.get('/:messageId', messagesController.getMessage);
app.get('/', messagesController.getAllMessages);
};
The problem is that the getAllMessages function doesn't have access to the 'userId' parameter (with value of 5), which is required in order to make an appropriate query to the database. The getAllMessages function in the controller expects the userId to be stored on req.params.userId. Is there any way to get the userId of 5 to be present on the req.params object inside the getAllMessages function?
The req.params are not passed down the route chain. To do so, you could do something like
In server.js, create a key on req. This will pass on your data between routes. Do this before mounting the routes.
app.use(function (req, res, next) {
req._data = {};
next();
});
In config/middleware.js,
module.exports = function(app, express) {
var usersRouter = express.Router();
var messagesRouter = express.Router();
// attach usedId
app.use('/users/:userId/messages', function (req, res, next) {
req._data.userId = req.params.userId;
next();
});
// mount the router
app.use('/users/:userId/messages', messagesRouter);
app.use('/users', usersRouter);
require('../routers/users')(usersRouter);
require('../routers/messages')(messagesRouter);
};
This way, you would have access to req._data.userId in routers/messages.js.
Side note: A better way to structure the routes would be to use something like, (read shameless plug), https://github.com/swarajgiri/express-bootstrap/blob/master/web/routes.js
You can use app.locals or res.locals to pass some datas.
There is a good explanation about locals.
An usage sample:
app.locals.userid = req.params.userId; //binding userid
app.locals.userid // => '5'
OR: put a global variable.
user_id_tmp = req.params.userId;
Now this is become global variable in app. So you can call user_id_tmp variable from anywhere.
I was looking for same.
Here is modules app example on github and auther site
Also we can change or update structure base on our requirements

Limit Node express to specific hostnames?

What's the best way to reject requests to my web server (running via Node express) that are coming in to an unrecognized hostname? I.e. I only want to respond to requests that are intended for my domain, not for requests that are just aimed at my IP address.
The easiest way would probably be to use the connect vhost middleware.
Where you would normally do this:
var app = express();
app.get('/', function(req, res){
res.send('HI');
});
app.listen(80);
You would do this:
var vhostApp = express();
vhostApp.get('/', function(req, res){
res.send('HI');
});
var app = express();
app.use(express.vhost('example.com', vhostApp));
app.listen(80);

access to HTTP server object in node.js express

I am inside a middleware (function(req, res, next) {...}).
Is there a way to access the HTTP server object from the req?
UPDATE
Let me be more specific. I am trying to find out a port that the server listens on, or unix socket path, if it's listening on that.
How about in your main app file:
var express = require('express');
var http = require('http');
var app = express();
app.use(app.router);
app.get('/', function (req, res, next) {
console.log(req.socket.server);
});
app.server = http.createServer(app);
app.server.listen(3000);
As Brad mentioned, Express does expose something resembling the object returned from #createServer(), however, TJ has been giving serious consideration to dropping any inclusion of the HTTP module in express in future releases. Using the code above will be future safe.
If what you are trying to do is expose the server object inside your routers, then yeah, middleware is the way to go:
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
app.use(function(req, res, next){ //This must be set before app.router
req.server = server;
next();
});
app.use(app.router);
server.listen(3000);
The middleware is used to expose the server object. Then, you can just access it in any of your routers like so:
app.get('/', function (req, res, next) {
console.log(req.server.get('port')); // displays 3000
});
Function app.listen returns your http server.
Source express/lib/application.js
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
for some reason, for me request.app.server did not work, probably because I was using express 4, after bit of digging up, I found that req.socket.server works.

Resources