I would like to implement Node.js with Express for static content over HTTPS. Scouring the Web reveals tons of examples of Express with HTTPS and tons of examples of Express serving a static directory, but I cannot find an example using all three Express, HTTPS and static.
Moreover, looking at the examples I can find, I cannot piece together how to accomplish this.
Here is what I have found:
Express Static Directory over HTTP
var fs = require('fs')
var app = require("express");
var server = app();
server.use(app.static(staticDir))
server.listen(webPort)
Express over HTTPS (without Static Directory)
const app = require('express')();
const https = require('https');
const server = https.createServer(
{
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.cert')
},
app
);
server.listen(APIPort);
When I try combining the two approaches, I get stuck because the static example bypasses createServer, and yet createServer is the crux of getting to HTTPS in the examples.
I'm sure the answer is simple, but I cannot arrive at or locate the solution.
Could you try the below code-snippet and see if it works for you?
const fs = require('fs');
const https = require('https');
const express = require('express');
const app = express();
app.use(express.static(process.env.SERVE_DIRECTORY));
app.get('/', function(req, res) {
return res.end('Serving static files!');
});
const key = fs.readFileSync(__dirname + '/selfsigned.key');
const cert = fs.readFileSync(__dirname + '/selfsigned.crt');
const options = {
key: key,
cert: cert
};
const server = https.createServer(options, app);
server.listen(PORT, () => {
console.log(`Serving on port ${PORT}`);
});
Please make sure to do the suitable changes before running the above code.
Related
I've been working at making a website, but after getting my website to work I set out to try and get SSL so the annoying "warning" symbol would go away. Unfortunately I've come to a real impasse and all the resources I've found to help me work through this seem to be outdated or at least not compatible with what I'm doing.
My original working server.js file:
const express = require('express');
const path = require('path');
const app = express();
const port = process.env.PORT || 3000;
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, '/index.html'));
});
app.listen(port);
What I tried but ends up not working:
const fs = require('fs');
const options = {
cert: fs.readFileSync('cert/certificate.crt'),
ca: fs.readFileSync('cert/ca_bundle.crt'),
key: fs.readFileSync('cert/private.key')
};
const express = require('express');
const path = require('path');
const app = express();
const port = process.env.PORT || 3000;
const httpsPort = process.env.PORT || 3030;
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, '/index.html'));
});
app.listen(port);
httpsPort.createServer(options, app).listen(httpsPort);
I am struggling to wrap my head around the entire venture since I've started on this https issue.
Help would be greatly appreciated!
Uhm, there are a few issues here. First you try to listen on two different things. app.listen is a short version of http.createServer({ ...options }, app).
Second - your code is httpsPort.createServer(options, app).listen(httpsPort);, which basically translates to 3030.createServer(options, app).listen(3030). Here's what I usually do:
const https = require('https');
const server = https.createServer(options, app).listen(port)
If you would like to support both, then you need to include both http and https packages, and have an if-else (or something similar) so that you use the proper package to create the server.
You should not listen on the app in this scenario!
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
var app, certificate, credentials, express, fs, http, httpServer, https, httpsServer, privateKey;
fs = require('fs');
http = require('http');
https = require('https');
privateKey = fs.readFileSync('key.pem', 'utf8');
console.log(privateKey);
certificate = fs.readFileSync('cert.pem', 'utf8');
console.log(certificate);
credentials = {
key: privateKey,
cert: certificate
};
express = require('express');
app = express();
httpServer = http.createServer(app);
httpsServer = https.createServer(credentials, app);
httpServer.listen(80);
httpsServer.listen(443);
I am on OS X and I have confirmed nothing else is listening on 80 and 443. I run this as sudo and when I go http://127.0.0.1, it works. However, when I go to https://127.0.0.1, I get not found.
What am I doing incorrect?
To enable your app to listen for both http and https on ports 80 and 443 respectively, do the following
Create an express app:
var express = require('express');
var app = express();
The app returned by express() is a JavaScript function. It can be 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 using the same code base.
You can do so as follows:
var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
var app = express();
var options = {
key: fs.readFileSync('/path/to/key.pem'),
cert: fs.readFileSync('/path/to/cert.pem')
};
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
For complete detail see the doc
add the following line of code:
app.listen(443);
Also, try getting rid of all of the http module, as express handles most of that for you. Look at the beginning Hello World for Express, http://expressjs.com/starter/hello-world.html and look for the part where it handles the port.
I'm successfully listenin port 443 and can access server over https, but I can't access it with http.
var fs = require('fs')
options = {
ca : fs.readFileSync('./ssl/site.com.pem'),
key: fs.readFileSync('./ssl/site.com.key'),
cert: fs.readFileSync('./ssl/site_com.crt')
}
var app = require('express.io')
app.https(options).io()
....
app.listen(443);
I've tried using http and https modules:
app.http().io();
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
But this time socket.io is giving 404 in browser. How can I solve this? I need to use Express.Io's socket connection because application is based on it.
You should redirect http to https
var express = require('express'),
app = express(),
httpapp = express();
//........................
var credentials = {key: privateKey, cert: certificate, ca: ca};
var httpsServer = https.createServer(credentials, app);
var httpServer = http.createServer(httpapp);
httpsServer.listen(443);
httpServer.listen(80);
httpapp.route('*').get(function(req,res){
res.redirect('https://yourdomain.com'+req.url)
});
Had the same problem a few days ago, and this GitHub issue helped:
https://github.com/techpines/express.io/issues/17#issuecomment-26191447
Your code is on the right way, it just need some changes. The code below is a slightly modified version of the snippet you provided.
var fs = require('fs'),
express = require('express.io');
options = {
ca : fs.readFileSync('./ssl/site.com.pem'),
key: fs.readFileSync('./ssl/site.com.key'),
cert: fs.readFileSync('./ssl/site_com.crt')
};
var app = express();
app.https(options).io();
var httpServer = require('http').createServer(app);
// ...
app.listen(443);
express.io.listen(httpServer);
httpServer.listen(80, function() { }, function() { });
Before, in an older version of express, I could do this:
express.createServer({key:'keyFile', cert:'certFile'});
However, in newer versions of express this no longer works:
var app = express();
Should I call app.use() to set the certs? If so how?
See the Express docs as well as the Node docs for https.createServer (which is what express recommends to use):
var privateKey = fs.readFileSync( 'privatekey.pem' );
var certificate = fs.readFileSync( 'certificate.pem' );
https.createServer({
key: privateKey,
cert: certificate
}, app).listen(port);
Other options for createServer are at: http://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener
I was able to get SSL working with the following boilerplate code:
var fs = require('fs'),
http = require('http'),
https = require('https'),
express = require('express');
var port = 8000;
var options = {
key: fs.readFileSync('./ssl/privatekey.pem'),
cert: fs.readFileSync('./ssl/certificate.pem'),
};
var app = express();
var server = https.createServer(options, app).listen(port, function(){
console.log("Express server listening on port " + port);
});
app.get('/', function (req, res) {
res.writeHead(200);
res.end("hello world\n");
});
This is my working code for express 4.0.
express 4.0 is very different from 3.0 and others.
4.0 you have /bin/www file, which you are going to add https here.
"npm start" is standard way you start express 4.0 server.
readFileSync() function should use __dirname get current directory
while require() use ./ refer to current directory.
First you put private.key and public.cert file under /bin folder,
It is same folder as WWW file.
no such directory found error:
key: fs.readFileSync('../private.key'),
cert: fs.readFileSync('../public.cert')
error, no such directory found
key: fs.readFileSync('./private.key'),
cert: fs.readFileSync('./public.cert')
Working code should be
key: fs.readFileSync(__dirname + '/private.key', 'utf8'),
cert: fs.readFileSync(__dirname + '/public.cert', 'utf8')
Complete https code is:
const https = require('https');
const fs = require('fs');
// readFileSync function must use __dirname get current directory
// require use ./ refer to current directory.
const options = {
key: fs.readFileSync(__dirname + '/private.key', 'utf8'),
cert: fs.readFileSync(__dirname + '/public.cert', 'utf8')
};
// Create HTTPs server.
var server = https.createServer(options, app);