Node.js: url route with the CNAME record - node.js

I want to map example.org and cname.example.org to two different node.js app.
But use no http web server such as nginx.
And the web framework is express.
So is there are any middleware in express or node.js to do this?

Express uses connect so you can do this:
var express = require('express'),
app = express();
app.use(express.vhost('example.org', require('./exampleApp/')));
app.use(express.vhost('cname.example.org', require('./cnameExampleApp/')));
app.listen(80);
There is also an example on github:
https://github.com/visionmedia/express/tree/master/examples/vhost
And here the reference for connect.vhost:
http://www.senchalabs.org/connect/vhost.html
Edit: In recent express versions, most middlewares like vhost are not included, so you will have to install them manually.
First, run:
$ npm install --save vhost
Updated code snippet:
const express = require("express");
const vhost = require("vhost");
const app = express();
app.use(vhost("example.org", require("./exampleApp/")));
app.use(vhost("cname.example.org", require("./cnameExampleApp/")));
app.listen(80);

You need a proxy like nginx in anyway if your 2 node apps are hosted on the same host.
var request = require('request');
var proxy = require('http').createServer(function (req, res) {
// distribute by request header 'host'
var targetHost = req.headers.host;
if (targetHost === 'example.org') {
req.pipe(request('http://your-node-app1' + req.url)).pipe(res);
} else if (targetHost === 'cname.example.org') {
req.pipe(request('http://your-node-app2' + req.url)).pipe(res);
} else { // not found or host is invalid
res.statusCode = 404;
res.end('host is not found!');
}
});
proxy.listen(80); // assume it listens to port 80

Related

Routes are not working in cPanel deployed json-server

I recently tried to deploy json-server to my interserver's shared hosting plan via cPanel.
I uploaded the app and configured a Node.js app and I'm able to access the endpoint via 'https://soltonbaev.com/json-server/api/contacts' however the jsonServer.rewriter() is not rewriting the "/api/" route to the "/".
In addition I cannot access the individual object via it's id, like for instance "https://soltonbaev.com/json-server/api/contacts/1". Server returns 404.
So clearly, JSON server is not picking up the routes when it is supposed to.
Here is the content of my server.js file
require('dotenv').config();
const jsonServer = require('json-server');
const cors = require('cors');
const server = jsonServer.create();
const router = jsonServer.router('database.json');
const middlewares = jsonServer.defaults();
const port = process.env.PORT || 3000;
server.use(
jsonServer.rewriter({
'/api/*': '/$1',
})
);
server.use(cors({origin: process.env.REMOTE_CLIENT_APP, credentials: true}));
server.use(middlewares);
server.use(router);
server.listen(port, () => {
console.log(
`🚀 JSON Server is running on ${process.env.REMOTE_CLIENT_APP}:${port}}`
);
});

How to ensure requests to my servers functions only by a single origin / UI?

I have a node.js server that has HTTP CRUD functions to my mongoDB.
And an Android application that sends requests though those functions.
I would like to ensure that my server will answer requests from specific origins.
For example: only answer requests from the android app, or my pc postman's requests.
How can I ensure that no one else sending requests using the same urls and ports will get answered?
This is my server.js file:
const express = require('express');
const MongoClient = require('mongodb');
const bodyParser = require('body-parser');
var db = require('./config/db');
var app = express();
const port = 8000;
app.use(bodyParser.json());
MongoClient.connect(db.url, (err, database) => {
if (err) return console.log(err)
db = database.db("getremp")
require('./app/routes')(app, db);
app.listen(process.env.PORT || port, () => {
console.log("Express server listening on port %d in %s mode - We Are lIVE!",app.settings.env.port, app.settings.env);
});
})
and my index.js:
const noteRoutes = require('./note_routes');
module.exports = function (app, db) {
noteRoutes(app, db);
};
You can control this with :
Send a specific header with your datas containing a secret key, then control the header in your node app How to check headers in nodejs?
Use HMAC in order to authenticate the user and control the integrity of datas : Node Hmac Authentication
But you've to remember that all traffic going out from an mobile app can be intercept (with Fiddler for example). Never use a static (non-dynamic) value to ensure authentication

Include CSS and JS in HTTP server?

I saw that you can use connect to use serve static files in a Node.js HTTP server like this:
var http = require('http');
var connect = require('connect');
var app = connect().use(connect.static(__dirname + path));
http.createServer(app).listen(8080);
How would I implement this in my current handler?
var http = require("http");
var handler = function(request, response){
// code
}
http.createServer(handler);
Is this even possible? If so, how can I accomplish it?
Unless you want to use an older version of connect that might not function properly, you'd have to install serve-static to do what you're trying to do. See this answer https://stackoverflow.com/a/24347442/5382465
var finalhandler = require('finalhandler')
var http = require('http')
var serveStatic = require('serve-static')
// Serve up public folder
var serve = serveStatic('public', {'index': ['index.html', 'index.htm']})
// Create server
var handler = http.createServer(function onRequest (req, res) {
serve(req, res, finalhandler(req, res))
})
// Listen
handler.listen(3000)

Node.js server with http get json

I want to create a simple Node.js server to do the following :
With my application I just do the command http.get(Node.Js_Server_address/json) to get the json file data stored on my server.
Could please help me with a tutorial? Any help would be appreciated!
This is very simple example of node.js server:
var app = require('./app');
var http = require('http');
var server = http.createServer(app);
server.listen(8080, function() {
console.log("listening to: http://127.0.0.1:8080");
});
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
there is a nice tutorial here and here ...
you can use npm to install node.js and all the packages that you need for it.
hope it helps.
There are lots of examples on this topic, i think you should make some googling before next time.
You can create a REST server via express module of nodeJs. In your server folder use npm install express to download express module. You can get more information about express from here. After that create a server.js file in your server folder.In server.js
var express = require('express');
var app = express();
var PORT = 8080;
/* req stands for request, res stands for response */
app.get('/json',function(req,res){
res.json(yourData);
})
app.listen(PORT,function(){
console.log('Express is listening port:' + PORT + '!');
})
So this should do the work. Let me know if this helps you.

Host multiple websites using Node.js Express

I am having problems configuring two different Node.js applications with different domains. Have two directories
"/abc/" -> express-admin setup (backend) -> admin.abc.com
and
"/xyz/" -> express setup (frontend) -> abc.com
I need admin.abc.com to point to express-admin setup and abc.com to express setup. I have vhost installed and both the site listens to port 80.
Have added
app.use(vhost('abc.com', app)); // xyz/app.js file
app.use(vhost('admin.abc.com', app)); // abc/app.js file
My problems:
forever is installed, whenever i start both the apps, the second one is always stopped. I tried using different port for both apps but still having the same error. Individually they run without problems.
I think my setup is too complicated for domain forwarding. Any better suggestions? May be I have a master app.js file which I can use to route the domains to their respective apps without using the app.js of each applications.
I am not sure how you are using the vhost. First of all with vhost approach, you need to run only one express app. Not two. Here is an example.
var express = require('express');
var vhost = require('vhost');
/*
edit /etc/hosts:
127.0.0.1 api.mydomain.local
127.0.0.1 admin.mydomain.local
*/
// require your first app here
var app1 = require("./app1");
// require your second app here
var app2 = require("./app2");
// redirect.use(function(req, res){
// if (!module.parent) console.log(req.vhost);
// res.redirect('http://example.com:3000/' + req.vhost[0]);
// });
// Vhost app
var appWithVhost = module.exports = express();
appWithVhost.use(vhost('api.mydomain.local', app1)); // Serves first app
appWithVhost.use(vhost('admin.mydomain.local', app2)); // Serves second app
/* istanbul ignore next */
if (!module.parent) {
appWithVhost.listen(8000);
console.log('Express started on port 8000');
}
You just need to run the main express app with vhost enabled using forever.
You're hosting the applications on the same port, using the same network interface. So when the second app starts, it will always find the port in use. If you want to use multiple applications on the same port, they each need to have their own network interface. When using vhost, you would still need to listen on a different port for each app. See this example for details. If you would like your apps to be completely independent, you're better off using node-http-proxy. This allows you to host a proxy on port 80 which forwards requests to express apps listening on different ports. If one of these apps crashes, it will not crash the other app, unlike the vhosts approach. This post gives an example of the implementation using node-http-proxy.
Thanks #veggiesaurus for pointing up to node-http-proxy. Apologies for posting late.
Here is how I solved my problem using node-http-proxy
Folder Structure:
www/
server.js
abc/ [express setup]
app.js
xyz/ [express-admin setup]
node_modules/express-admin/app.js
"abc" and "xyz" have there own setup and running on port x.x.x.x:3001 and x.x.x.y:3002
I installed node-http-proxy and added server.js file with following codes. Referred this link
var http = require('http');
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxy();
var options = {
'abc.com': 'http://x.x.x.x:3001',
'xyz.com': 'http://x.x.x.y:3002'
}
http.createServer(function(req, res) {
proxy.web(req, res, {
target: options[req.headers.host]
});
}).listen(80);
Finally, used forever to run all 3 apps setup to run forever in port 3001, 3002 and 80.
const express = require("express");
const app = express();
const fs = require('fs');
app.use((req, res, next) => {
let reqDomain = req.get("host");
if (reqDomain.indexOf(":") > -1) {
reqDomain = reqDomain.split(":")[0];
}
if(reqDomain.endsWith(".local")) {
reqDomain = reqDomain.substring(0, reqDomain.length - 6);
}
const domainPath = "public/" + reqDomain;
let filePath = domainPath + req.originalUrl;
filePath = fs.lstatSync(filePath).isDirectory() ? filePath + "/index.html" : filePath;
console.log(__dirname + "/" + filePath);
res.sendFile(filePath, { root: __dirname });
});
const port = process.env.PORT || 80;
app.listen(port, () => console.log("Server Started on Port " + port));
Inside public directory put you folder like 'my-first-website.com', 'my-second-website.com'
To test locally add following in /etc/hosts
127.0.0.1 my-first-website.com.local
127.0.0.1 my-second-website.com.local

Resources