I have in my private network different services, these services are not accessible from the out side (externe).
I'd like that my services be accessible to some users, and this after an authentication process (for this part I use express).
Once the user is authentificared it will be proxiate to the right service, I tried for this the http-proxy module.
Problem:
I failed to use correctly http-proxy with express module, and resolve this enigma as wished.
Code:
I began by doing this
// Create app with Express
var express = require('express');
var app = express();
// Create a proxy server with http-proxy
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer();
// Create target params (in the local network)
var serverOne = {target:'ws://172.17.0.3:80',ws:true};
// The use of proxy to expose the service
app.all("/app/", function(req, res) {
console.log('redirecting to Server1');
proxy.web(req, res, serverOne);
})
// The login part
.get('/login', function(req, res) {
res.render('login.ejs');
console.log('Cherche Login');
})
app.listen(8080);
Result:
Can someone help me please to fix this?
Try changing var serverOne = {target:'ws://172.17.0.3:80',ws:true};
to var serverOne = {target:'ws://172.1.0.3:80',ws:true};
Also check that from the server 104.155.15.204, you are able to access the 172.0.1.x network
You can have a look at http://expressjs.com/fr/api.html for implementation of proxies on express.
Regards,
Marc
Related
General information about my setup
Currently I am building a web application using react and a nodejs API that is providing the data for this web application. Both apps are hosted on heroku.com and run independently from each other. I have bought a custom domain from a different hosting provider and used the heroku custom domain option to point the DNS to my website.
Technical details about my setup
NodeJS server: Express
NodeJS version: v10.15.0
React version: v16.2.0
Custom domain: www.tabbs.nl
Heroku domain: tabbs-web-app.herokuapp.com
The issue I am experiencing
I have been digging into a lot of documentation and tutorials in order to setup SSL for react / NodeJS but couldn't find a decent tutorial about how to set SSL / security for my setup.
Tutorials I already have read:
Node + Express + Lets Encrypt
How to use SSL/TLS with nodejs
Stack overflow posts and probably a whole lot more I am forgetting right now.
What do I want to achieve?
The goal I would like to achieve is setting up a secure connection between React web application (frontend) and NodeJS API (backend) so that all data between those is encrypted and safe. Also I want my custom domain (bought by a different hosting provider than Heroku) to be secure and forced using https.
For any questions or additional information please do not hesitate to ask!
Have you tried using the https module in node?
You can do something like this:
var express = require('express');
var https = require('https');
var http = require('http');
var app = express();
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
The app returned by express() is in fact a JavaScript Function, designed to be passed to Node’s HTTP servers as a callback to handle requests. This makes it easy to provide both HTTP and HTTPS versions of your app with the same code base, as the app does not inherit from these (it is simply a callback.
If you are using create react app, open your terminal and type “npm run build”. This creates a build folder with all of your static files.
Now go back to your node backend service and add the following:
var express = require('express');
var path = require('path');
var https = require('https');
var http = require('http');
var app = express();
const options = {
key: fs.readFileSync("/srv/www/keys/my-site-key.pem"),
cert: fs.readFileSync("/srv/www/keys/chain.pem")
};
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
If you’re using react router to handle routing for you web app then you would amend the GET request as such:
var express = require('express');
const path = require('path');
var https = require('https');
var http = require('http');
var app = express();
const options = {
key: fs.readFileSync("/srv/www/keys/my-site-key.pem"),
cert: fs.readFileSync("/srv/www/keys/chain.pem")
};
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
This ain't a complex issue, do not worry about ssl, just create your own certificate for Node.JS/Express and that's enough.
and, React has a built-in way of doing api calls,
add this line to package.json of your React installation,
"proxy": "http://localhost:8000/"
and just call the api service like this,
//Generic API Call
callApi = async () => {
const response = await fetch('/api/hello');
const body = await response.json();
if (response.status !== 200) throw Error(body.message);
return body;
};
// A Submit handler to proxy
handleSubmit = async e => {
e.preventDefault();
const response = await fetch('/api/myrequest', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ post: this.state.post }),
});
const body = await response.text();
this.setState({ responseToPost: body });
};
it all works.
I am a newbie in node.js, but I have a sample application written for node.js that shows the way of integration with specific Identity Provider (SAML). Using this sample app I am trying to inspect what is sent in the HTTP requests made from the node.js backend to the remote IdP. Logging the request headers and body by writing to the console.log would be enough for me. Monitoring the network traffic with some tool like Fiddler is not an option for me, because I cannot run it locally, I need to have the app exposed and I have it deployed to Heroku.
I've tried morgan, but it only intercepts the INCOMING requests. I've also tried global-request-logger, but for some reason it does not inject itself into the express framework and passport. Seems like passport is not using the standard modules for HTTP requests?
The question is: what I need to use to be able to log the content of the HTTP requests made by passport during the .authenticate() call? Is there any flag that I am able to set in passport to enable HTTP logging? Or should I rather do it in express? Or maybe some other package would provide the functionality I need?
EDIT:
My original question was marked as possible duplicate of how to log OUTGOING https requests from node within webstorm
But actually I have already seen that topic and I've tried to setup a hook to http module, it was done this way:
'use strict';
// Setup express.js application:
var express = require('express');
var app = express();
// Patch "http" module with outgoing request logging:
var http = require('http');
const originalRequest = http.request;
http.request = function wrapMethodRequest(req) {
console.log('EXTERNAL OUTGOING REQUEST LOGGING:');
console.log(req.host, req.body);
return originalRequest.apply(this, arguments);
}
This approach was not working. As already said in the original question, it seems that passport does not use standard http module? Or did I something wrong with the code above?
As already mentioned in the original question, I was also trying to handle it via global-request-logger package (which as explained in the possible duplicated post, uses the same technique). The code for that was:
'use strict';
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var passport = require('passport');
var SamlStrategy = require('passport-saml').Strategy;
app.use(bodyParser.urlencoded({ extended: false }));
var globalLog = require('global-request-logger');
globalLog.initialize();
globalLog.on('success', (req, res) => {
console.log('HTTP(S) CALLOUT SUCCESS');
console.log('REQUEST: ', req);
console.log('RESPONSE: ', res);
});
globalLog.on('error', (req, res) => {
console.log('HTTP(S) CALLOUT ERROR');
console.log('REQUEST: ', req);
console.log('RESPONSE: ', res);
});
...
On my local JavaScript, I want to make a rest call to
/rest/speakers
and have that proxied to
http://localhost:2011/rest/speakers
I have code as follows that does not quite work as I want:
var proxy = require('express-http-proxy');
var app = require('express')();
app.use('/rest', proxy('localhost:2011/'));
app.listen(8081, function () {
console.log('Listening on port 8081');
});
To make the proxy work, I actually need to call
/rest/rest/speakers
I kind of get it. It seems that I'm proxying my /rest to the root of localhost:2011 and then I need to dive into the /rest of that server. Adding /rest to the end of the proxy(..) is ignored.
Try using proxyReqPathResolver to modify your URL as needed.
var url = require('url'),
proxy = require('express-http-proxy');
// ... other app setup here
app.use('/rest', proxy('localhost:2011', {
proxyReqPathResolver: function(req, res) {
return '/rest/rest' + url.parse(req.url).path;
}
}));
I'm developing a web application using nodejs and I need a reverse proxy for this application.
In many places it is noticed that nginx is used as a reverse proxy.
My questions are
1. "Is there any ready made nodejs based reverse proxy?"
2. "Is it a good idea to implement a nodejs based reverser proxy?"
3. "It is advised to use nginx?"
4. Why is nginx is considered in first place for reverse proxy?
--Ganesh
use following command to install Express.js and http-proxy.
npm install --save express http-proxy
In order to run the reverse proxy server we need some resource server from which Proxy will fetch data.So to do that, develop three Express server running on Port 8000,8001,8002 respectively.
Server.js
var express = require("express");
var app = express();
app.get('/app1',function(req,res) {
res.send("Hello world From Server 1");
});
app.listen(8000);
write the same code for other servers too and change the text.
Example of proxy server code in express.js with multiple targets.
app.js (file)
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var serverOne = 'http://localhost:8000',
ServerTwo = 'http://localhost:8001',
ServerThree = 'http://localhost:8002';
app.all("/app1/*", function(req, res) {
console.log('redirecting to Server1');
apiProxy.web(req, res, {target: serverOne});
});
app.all("/app2/*", function(req, res) {
console.log('redirecting to Server2');
apiProxy.web(req, res, {target: ServerTwo});
});
app.all("/app2/*", function(req, res) {
console.log('redirecting to Server3');
apiProxy.web(req, res, {target: ServerThree});
});
app.listen(8000);
You can add as many targets as you want and it will create a proxy for that.Check whether its working or not by first run all the servers and hit request to /app1 and /app2 etc.
I found the DProx node plugin an absolute must. Allows for most of the configuration that one would need from a Reverse proxy server, while making it simple JSON config.
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);