Cannot open site with https server using Express - node.js

var fs = require('fs'),
https = require('https'),
express = require('express'),
app = express();
https.createServer({
key: fs.readFileSync('./ssl/key.pem'),
cert: fs.readFileSync('./ssl/cert.pem')
}, app).listen(55555);
app.get('/', function (req, res) {
res.header('Content-type', 'text/html');
return res.end('<h1>Hello, Secure World!</h1>');
});
I tried many times about using https server based on express, while I still cannot open the site, for example using Chrome:
It says "No data received" and "ERR_EMPTY_RESPONSE".
So it is listening, but the response cannot be sent to client, why?
Thank you!

Related

Certifiction error from chrome browser using ReactJS

i am trying to send an https request from my frontend (reactjs) to backend (nodejs/express).
These two both run in localhost.
Back end server code:
const app = require('./app')
const https = require('https');
const fs = require('fs');
const credentials = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
//connect to the database
require('./db')
const port = 8765;
app.get('/', (req, res) => {
res.send('Now using https..');
});
var server = https.createServer(credentials, app);
//var server = https.createServer(app);
// listen for requests
server.listen(port, () => {
console.log("server starting on port : " + port)
});
front end request:
const {data: Sessions}= await axios.get("https://localhost:8765/...");
i am trying to send an https request from my frontend (reactjs) to backend (nodejs/express).
These two both run in localhost.
Back end server code:
const app = require('./app')
const https = require('https');
const fs = require('fs');
const credentials = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
//connect to the database
require('./db')
const port = 8765;
app.get('/', (req, res) => {
res.send('Now using https..');
});
var server = https.createServer(credentials, app);
//var server = https.createServer(app);
// listen for requests
server.listen(port, () => {
console.log("server starting on port : " + port)
});
front end request:
const {data: Sessions}= await axios.get("https://localhost:8765/...");
doing this request from postman with the exact same parameters produces the desired result.However when i try to do this from frontend i get: GET https://localhost:8765/... net::ERR_CERT_AUTHORITY_INVALID in react chrome extention.I believe this is because i am using a self signed certificate and chrome browser can't verify it's validity.
Is there a way to temporarily disable this verification step from chrome?
If not how else can i solve this?
Not : Doing this with HTTP works fine but i need it to be HTTPS.
If your just going to run it on local host one your machine you can disable the setting at chrome://flags/#allow-insecure-localhost in browser.
This will not fix anything in production tho, only for personal use.

How can I adjust my NodeJs server code to responf to HTTPS requests?

I have a small nodejs server which is working without a problem. Now I am trying to make use of "HTTPS" for security reasons. I have the following code, but when I try to open the page in Firefox via link [http://192.168.2.22:8080/api/users], on the terminal I see DIRECTING >>> https://192.168.2.22:8080/api/users but in the browser, instead of the expected response, I encounter this error:
Secure Connection Failed An error occurred during a connection to
192.168.2.22:8080. SSL received a record that exceeded the maximum permissible length.
Error code: SSL_ERROR_RX_RECORD_TOO_LONG
// Modules /////////////////////////////////////////////////////////////////////
const db = require('./db.js');
// Packages ////////////////////////////////////////////////////////////////////
const colors = require('colors');
const express = require('express');
const app = express();
const fileUpload = require('express-fileupload');
const fs = require('fs');
// Constant Variables //////////////////////////////////////////////////////////
const PORT_SERVER = 8080;
const HOST = '192.168.2.22';
////////////////////////////////////////////////////////////////////////////////
app.use(express.json({limit: '50mb'}));
// app.use(express.urlencoded({limit: '50mb'}));
// set up a route to redirect http to https
app.get('*', function(req, res) {
console.log('DIRECTING >>> https ://' + req.headers.host + req.url);
res.redirect('https://' + req.headers.host + req.url);
});
app.get('/api/users/', async (req, res) => {
console.log('CHECK POINT !!!');
let users = await db.db.get_users();
console.log("USERS : " + users);
res.send(users);
});
// have it listen on 8080
app.listen(PORT_SERVER, () => console.log(`Listen at ${PORT_SERVER}...`));
How can I resolve this? I could not find a solution that I can easily apply to my code, I am kind of a newbie for NodeJs.
Thanks in advance
You have not configured your server for SSL. Configure SSL using the https module like below. In this example, I have created two express one for Http and one for https as we can not run both http and non https on same port.
const express = require('express');
const http = require('http'),
const https = require('https')
const fs = require('fs')
const httpApp = express()
const app = express()
const httpsOptions = {
key: fs.readFileSync("server.key"),
cert: fs.readFileSync("server.crt")
};
httpApp.set('port',80);
httpApp.get("*", function (req, res, next) {
res.redirect("https://" + req.headers.host + "/" + req.path);
});
app.set('port', 443);
app.enable('trust proxy');
http.createServer(httpApp).listen(httpApp.get('port'), function() {
console.log('Express HTTP server listening on port ' + httpApp.get('port'));
});
https.createServer(httpsOptions, app).listen(app.get('port'), function() {
console.log('Express HTTPS server listening on port ' + app.get('port'));
});
The Best way to redirect from non-http to https is to use Nginx web server as a reverse proxy and define redirection rule in Nginx config file.
client--->nginx reverse proxy(with SSL and redirection rules)-->express server
try changing the port to 443, https runs on 443 by default!

ERR_CONNECTION_REFUSED when redirecting http to https using nodejs

I'm trying to redirect http requests to https using nodejs.
Here is my code so far. I have included all key, certs etc.
http and https ports are ON ( custom ports, not defaults)
Now on hitting http, site does get redirected to https but it shows err as shown in screenshot attached. screenshot.
certs are valid ( see bottom of screenshot ) but still it says THIS PAGE IS NOT SECURE.
Please guide me where i'm wrong and possible solution.
I have searched here but couldn't get solution to this. Thanks.
var fs = require('fs');
var http = require('http');
var http_port =any_port;
var app = require('express')();
// HTTPS definitions
var https = require('https');
var https_port =another_port;
var options = {
key: fs.readFileSync('example.key'),
cert:fs.readFileSync('example.crt'),
ca: fs.readFileSync('bundleexample.crt')
};
app.get('/', function (req, res) {
res.end('Hello https World!');
});
https.createServer(options, app).listen(https_port, function () {
console.log('https port ' + https_port);
});
// Redirect from http port to https
http.createServer(function (req, res) {
res.writeHead(301, { "Location": "https://" + req.headers['host'].replace(http_port,https_port) + req.url });
res.end();
}).listen(http_port);

Putting socket.io behind a reverse proxy?

I recently decided to learn socket.io, to make something real-time. I wrote something up, following the Get Started page on the site, and tested it locally until I got it working properly.
I uploaded it to my server using the same process as anything else. I ran it on port 8002, and added it to my reverse proxy (using http-proxy-middleware) under /pong/*. I then proxied /socket.io/* to port 8002 before it worked. However after inspection with Firefox I noticed that socket.io was only using polling as a transport method and not websockets, and after some further thought I decided that sending /socket.io/* to 8002 is not going to be good when using socket.io on other projects in the future.
So I ask, how do I get multiple socket.io programs running behind a reverse proxy, using websockets as a for transport?
proxy.js
const express = require("express")
const fs = require('fs');
const http = require('http');
const https = require('https');
const proxy = require('http-proxy-middleware');
const privateKey = fs.readFileSync('/etc/[path-to- letsencrypt]/privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/[path-to-letsencrypt]/cert.pem', 'utf8');
const ca = fs.readFileSync('/[path-to-letsencrypt]/chain.pem', 'utf8');
var credentials = {key: privateKey, cert: certificate, ca: ca};
var app = express();
app.use(function (req, res, next) {
console.log(req.url)
next()
})
app.use("/pong/*", proxy({ target: "http://localhost:8002", pathRewrite: {"^/pong": ""}, ws:true, changeOrigin: true }))
app.use("/pnw/war/*", proxy({ target: "http://localhost:8000" }))
app.use("/pnw/nation/*", proxy({ target: "http://localhost:8001" }))
app.use(express.static("./static"))
https.createServer(credentials, app).listen(443);
// Redirect all HTTP traffic to HTTPS
http.createServer(function (req, res) {
res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
res.end();
}).listen(80);
pong.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http, {
path: "/pong/"
});
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
http.listen(8002, function(){
console.log('listening on *:8002');
});
index.html
<script src="/pong/socket.io.js"></script>
<script>
var socket = io({
// transports: ['websocket'], upgrade: false, (using for testing)
path:"/pong"
})
// ...
</script>
What I have currently comes from following the answer to this question:
Setting up multiple socket.io/node.js apps on an Apache server?
However in the firefox console I get a warning which reads:
Loading failed for the <script> with source “https://curlip.xyz/pong/socket.io.js”, followed by an error io is not defined. In the network tab getting socket.io.js is showing a 404.
So what I believe is happening is that because express is capturing the requests for /, socket.io cannot (for some reason) server socket.io.js. However when I changed / to /index.html and loaded that there was no change.
So I did some more research and came upon a solution. I opened the port 8002 on my EC2 so that I could poke around looking for socket.io.js.
Essentially what I found is socket.io.js was located at /pong/pong/socket.io.js because I set path in pong.js to "pong", which, in hindsight make sense, the proxy adds one "pong", while socket.io itself is capturing "/pong".
Knowing this I removed the path option in pong.js, so that socket.io.js can be found at /pong/socket.io/socket.io.js. I then made the client point to this by changing the script tag and path option in index.html.
pong.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
http.listen(8002, function(){
console.log('listening on *:8002');
});
index.html
<script src="/pong/socket.io/socket.io.js"></script>
var socket = io({
path:"/pong/socket.io/"
})

https ssl/tls not working at localhost in Nodejs

https module not working at my localhost. I have go through this blog.mgechev.com tutorial. My node v5.10.1.
Here code:
//index.js
var fs = require('fs'),
https = require('https'),
express = require('express'),
app = express();
https.createServer({
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
}, app).listen(55555);
app.get('/', function (req, res) {
res.header('Content-type', 'text/html');
return res.end('<h1>Hello, Secure World!</h1>');
});
node index.js
Output:
It is silly mistake. I just hit url with preceding https and it working fine.
That is:-
https://localhost:55555

Resources