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);
Related
I know that using .htaccess file can restrict files to be served under .git but how do i acheive the same if i'm using node.js server. I use forever to start/stop the servers.
Below is the code.
const bodyParser = require("body-parser");
var request = require("request");
const dotenv = require('dotenv');
const app = express();
//app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(__dirname));
app.set('view engine', 'ejs');
dotenv.config();
var environment = process.env.NODE_ENV;
var endpoint = process.env.AUTOMATION_API_ENDPOINT;
var port = process.env.PORT;
console.log('Environment : '+ environment);
console.log('Server Port : '+ port);
console.log('BackEnd server Endpoint : '+ endpoint);
var supplierId = null;
var supplyApiEndpoint = null;
app.get("/", function(req,res,next){
var env=null;
var url = endpoint+'/v1/supply/qa/env';
require('http').get(url, (resp) => {
resp.setEncoding('utf8');
resp.on('data', function (response) {
var body = JSON.parse(response);
var supplyApiEndpoint = body.endpoint;
console.log("Endpoint: "+supplyApiEndpoint);
res.render('index',{env: supplyApiEndpoint});
});
});
})```
The forever is a tool for ensuring that a given script runs continuously and not a web framework.
To serve your files you will need to use a web framework like express and you will be able to ignore some directories serving only the files you need, for example, to serve your views directory:
app.set('views', path.join(__dirname, '/yourViewDirectory'));
or adding some rules using regex to ignore the files:
app.use([/^\/public\/secure($|\/)/, /(.*)\.js\.map$/, '/public'], express.static(__dirname + '/public'));
You can use other node.js web frameworks to do the same as fastify or koa.
I am using sslforfree for creating an https server with node.js, express.js. But whenever I try to access https://localhost it shows me error 403: access denied. My folder structure like this.
and my server.js goes here
var express = require('express')
, fs = require('fs')
, passport = require('passport')
, logger = require('mean-logger')
, http = require('http')
, https = require('https')
, path = require('path')
var env = process.env.NODE_ENV || 'production'
, config = require('./config/config')[env]
, auth = require('./config/middlewares/authorization')
, mongoose = require('mongoose')
var db = mongoose.connect(config.db)
var models_path = __dirname + '/app/models'
fs.readdirSync(models_path).forEach(function (file) {
require(models_path+'/'+file)
})
require('./config/passport')(passport, config)
var app = express()
require('./config/express')(app, config, passport)
require('./config/routes')(app, passport, auth)
var options = {
key: fs.readFileSync(path.resolve(__dirname,'config/ssl/patarboi.key')),
cert: fs.readFileSync(path.resolve(__dirname,'config/ssl/patarboi.crt')),
ca: fs.readFileSync(path.resolve(__dirname,'config/ssl/patarboi.ca'))
};
/*app.listen(port)
console.log('Express app started on port '+port)*/
logger.init(app, passport, mongoose)
// expose app
exports = module.exports = app
var port = process.env.PORT || 443
var server = https.createServer(options, app);
server.listen(port, function () {
console.log('server at port '+port);
});
You are trying to run your server on port 443. Remember your service needs to have root permission to listen to this PORT.
And most probably 443 will be in use already. You can check by netstat -a and see if 443 is in the list.
In windows, if you're using skype. This would also create some trouble when you try to use 443 PORT.
I am currently learning how to create servers with Node js and other Javascript apis, and I've built a both HTTP and HTTPS server which works fine on every pc navigator of my nat network but when I try the https server on my android mobile device with: https://192.168.1.20:8443 which is where I built my node.js server it won't load and say the page is not working although it works with http.
I would also like to know if I could make my server visible or access to it with my router public ip address and how could I do that.
This is my server code:
var fs = require('fs');
var http = require('http');
var https = require('https');
var cors = require('cors');
var privateKey = fs.readFileSync('host.key', 'utf8');
var certificate = fs.readFileSync('host.cert', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var app = express();
app.use(cors());
app.use('/work', express.static('/.'))
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
console.log('Servidor en marxa.');
});
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
httpServer.listen(8080);
httpsServer.listen(8443);
Some hours later I have just realized I needed to forward my router ports to where I have my Node.js server built. I had to port forward both the HTTP (#80) and HTTPS (#443) to grant the access by public ip address.
Also had to modify part of my Javascript Server code.
var fs = require('fs');
var http = require('http');
var https = require('https');
var cors = require('cors');
var privateKey = fs.readFileSync('host.key', 'utf8');
var certificate = fs.readFileSync('host.cert', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var app = express();
app.use(cors());
var path = require('path');
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
console.log('Servidor en marxa.');
});
// your express configuration here
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
httpServer.listen(80,"0.0.0.0");
httpsServer.listen(443,"0.0.0.0");
var io = require("socket.io")(httpServer);
I'm fairly new to this. I created a node-express server that runs locally. And I have a index.html under public\html folder. When I visit that index page, I got an error Can't render headers after they are sent to the client node server error. My understanding is that if the url is localhost:8080 plus /, index.html will be rendered? How do I solve this problem? Many thanks!
ps: The odd thing is that when I move index.html out from the "public" folder to the same directory with the node server.js, and change to app.get('/', function (req, res {fs.readFile('/index.html'.. the index.html seems to work fine.
var fs = require('fs');
var http = require('http');
var https = require('https');
var request = require('request');
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var path = require('path');
var express = require('express');
var app = express();
var certificate = fs.readFileSync( 'something.0.0.1.cert' );
var privateKey = fs.readFileSync('something.0.0.1.key');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
app.use(express.static(__dirname+'/public'));
app.get('/', function (req, res) {
fs.readFile('__dirname + '/public'+ '/html'+/index.html', function(error, content) {
if (error) {
res.writeHead(500);
res.end();
}
else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(content, 'utf-8');
}
});
res.send('Hello World');
});
https.createServer({
key: privateKey,
cert: certificate
}, app).listen(8080,'0.0.0.0');
You only get one response for every request. Your code shows res.send('Hello World');
change this to res.sendFile("__dirname + '/public/html/' + 'index.html' ")
You can remove the fs.readFile line too.
The reason fs.readFile('/index.html') works when you move to the same file as your server is because that line means to read a file called index.html from the same directory. But you want to send a response to a request, not just read files.
Check out the docs on res.sendFile in express
Try this:
app.get('/', function (req, res) {
res.sendFile(__dirname + '/public/html/'+'index.html');
});
I'm trying to configure my express server to use HTTPS but I am running into some issues. I followed the documentation to setup my HTTPS server but I am still encountering some errors.
Here's my app.js
var express = require('express');
var app = express();
var server = require('https').createServer(options, app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
var fs = require('fs');
var options = {
key: fs.readFileSync('/test/key.pem'),
cert: fs.readFileSync('/test/cert.pem')
};
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
When starting my server I encounter
https.js:32
if (process.features.tls_npn && !opts.NPNProtocols) {
^
TypeError: Cannot read property 'NPNProtocols' of undefined
at new Server (https.js:32:40)
at Object.exports.createServer (https.js:56:10)
So, I tried to define NPNProtocols within options, but that did not work. Anyone have any pointers here?
Thank you.
try this once, i think you should have certificate in .crt format. and you will require tls module.
var sslOptions = {
key: fs.readFileSync('public/server.key'),
cert: fs.readFileSync('public/server.crt')
};
tls.createServer(sslOptions, function (cleartextStream) {
var cleartextRequest = net.connect({
port: port,
host: serverStr
}, function () {
cleartextStream.pipe(cleartextRequest);
cleartextRequest.pipe(cleartextStream);
});
}).listen(443);
port is you http port . and sercerStr is you server address.
IMO, the issue is not with the extension of the keys, rather the ssl configuration used. Use https node module with correct ssl options for ca, cert, and key to enable https with express.
// server/index.js
const express = require('express');
const fse = require('fs-extra');
const helmet = require('helmet');
const https = require('https');
const path = require('path');
// path to cert files
const paths = {
certFile: '/path/to/cert.pem',
chainFile: '/path/to/fullchain.pem',
privateFile: '/path/to/privkey.pem',
};
/* Express implementation (ignore) */
const app = express();
app.use(helmet());
app.use(express.static(path.join(__dirname, '..')));
app.get('/', (request, response) => {
response.sendFile(path.join('index.html'));
});
// setup https
const setupHttps = () => {
const promises = [
fse.readFile(paths.chainFile),
fse.readFile(paths.privateFile),
fse.readFile(paths.certFile),
];
return Promise
.all(promises)
.then(data => {
const [ chainData, privateData, certData ] = data;
const options = {
ca: chainData.toString('utf-8'),
cert: certData.toString('utf-8'),
key: privateData.toString('utf-8'),
};
return https.createServer(
options,
app
).listen(443);
})
.catch(err => console.log(err));
};
return setupHttps();
EDIT: I used helmetjs for better security with http headers.