Https server response error - node.js

I'm developing a program that requires a https server and I also created the apropiate certificates. My problem start when I create the https server this way:
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end('Open ssl running');
}).listen(8080);
I don't want to response a simple text, what I want is to send my static folder located in public directory where are the controllers, htmls and so on.
I also tried to send directly the path.join(__dirname, 'public') but it does not work.
Thanks for help!

Solution
Delete the callback and:
https.createServer(options, app).listen(8080, function () {
console.log('Started!');
});
Where options are the keys and app the Express app. Also the express middleware for send the static code.

Related

Express server not redirecting HTTP to HTTPS

I am attempting to setup a server with ExpressJS which uses HTTPS and servers a React app. I want any HTTP requests to be redirected to using HTTPS.
Additional constraint: I am using React router, so the server needs to be able to handle that. e.g. if I request localhost:3000/profile, I want React Router to handle that, I just need Express to server up index.html as I had gone to localhost:3000.
Problem: I think I've been able to setup HTTPS (Chrome complains but I don't mind for now), but I cannot get redirection to work.
For comparison, this is my code for how I setup my HTTP-only server for development (before I ever tried to setup HTTPS):
const express = require('express');
const http = require('http');
const path = require('path');
const app = express();
const DIST_DIR = path.resolve('./dist');
app.use(express.static(DIST_DIR));
app.get('*', (req, res) => {
res.sendFile(path.resolve(DIST_DIR, './index.html'));
});
const devServer = http.createServer(app);
devServer.listen(3000);
Next, I started with this guide. I created a self-signed SSL certificate then set up my application. I then looked at some examples of how to redirect, such as this question.
However, it doesn't seem to be working.
Here is my code at present:
app.use(express.static(DIST_DIR));
app.use((req, res, next) => {
if (req.secure) {
next();
} else {
res.redirect(`https://${req.headers.host}${req.url}`);
}
});
app.get('*', (req, res) => {
res.sendFile(path.resolve(DIST_DIR, './index.html'));
});
const httpServer = http.createServer(app);
httpServer.listen(3080);
const privateKey = // uses FS to get my key
const certificate = // uses FS to get my cert
const credentials = { key: privateKey, cert: certificate };
const httpsServer = https.createServer(credentials, app);
httpsServer.listen(3443);
I can access https://localhost:3443 and navigate the app as expected, and Express properly handles refreshes on pages like /profile. Great. Chrome complains that "CA root certificate is not trusted. Install this cert in the trusted root certification authorities store" but I haven't put in the work to solve that, because in a real production environment I'd be provided the certificate and key from a trusted source.
However, when I go to http://localhost:3080, I just end up at http://localhost:3080. Chrome devtools shows I'm not using HTTPS. Furthermore, I can't go directly to /profile, as Chrome gives me the error "This site can’t provide a secure connection".
I've tried other methods listed in that stackoverflow question I linked, but they either have the same behavior or straight up don't work. I'm a bit out of my element here and I'm trying to learn, but I don't understand why this isn't working. Any help would be appreciated. Thanks.
While you can manage this in your application it is often the convention to have a web server like nginix or apache in front of your application that manages the https redirection. Depending on your setup it is also common to manage your certificates at this front server to simplify certificate management. If you are going to deploy onto aws or another cloud provider I would let their infrastructure handle this for you.

can node HTTPS server be created without public and private keys?

I am using expressjs to create an http/https server.
There was a case wherein the server was not able to fetch the public and private certificate files from a directory.
In which case I create the server using http and send a raw HTML file to the client indicating that there was an issue, but here lies the problem,
the user does not know that they need to move to http url rather than https to see the HTML file.
So is there a way I can redirect my users to a https url when they try to access the http URL
init.js
try {
// options = get public and private certificate file
} catch(e) {
// accessError
}
if(accessError) {
server = http.createServer();
} else {
server = https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('hello world\n');
});
);
}
server.listen(8080);
app.js
let app = require('express');
app.use((req, res, next) => {
if(accessError) {
res.sendFile(index.html);
} else {
next();
}
});
index.html
<h1> there was an error <h1>
You can try a 301 Redirect like in the answer to this question.
Whenever somebody tries to access the http variant of a resource, they'll be redirected to the https one.
As a design decision I'd treat the inability to retrieve certificates as a fatal error. I imagine you're reading them at start time. If you can't read them for some reason, you should just terminate the application, and log an exception. You do need to have some monitoring in place to notice that the thing hasn't started and act accordingly when you can't find it. But displaying an error page seems like more trouble than it's worth. You're going to have the application in an up state, but not really. Cause it won't be able to do anything, and you'll need to rely on clients telling you that it doesn't work and there's a https related message etc. Better to fail hard.

App.js functionality loss over public internet using NODE JS AND EXPRESS

Node js + express is displaying great on localhost. My issue is, is that after I display static page which is doing it's job, my app.js script is not firing from the outside world. But when running locally it works like it is suppose to.
//send html page to user
app.use(express.static(__dirname + '/node_modules'));
app.use(express.static('public'));
app.get('/', function(req, res, next) {
res.sendFile(__dirname + '/index.html'); //send the file
});
//My app
// everything below this line does not work
I followed the direction from express but still app.js is not firing from the outside world. Again it hits great on local. Any help that would be greatly appreciated!
https://expressjs.com/en/starter/static-files.html
Based on your code, I was able to deduce that you are behind a sockets enabled CDN and it has not cashed your server-side sockets. Turn off cashing if you are actively developing your site.

Can't load local files when using NodeJS server

I'm very new to NodeJS, and I'm currently playing around with it (and websockets), so this question might be a bit dumb. Anyway, I'm following a tutorial which has given me a simple app.js containing the following:
var fs = require('fs')
, http = require('http')
, socketio = require('socket.io');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-type': 'text/html'});
res.end(fs.readFileSync(__dirname + '/index.html'));
}).listen(8080, function() {
console.log('Listening at: http://localhost:8080');
});
socketio.listen(server).on('connection', function (socket) {
socket.on('message', function (msg) {
console.log('Message Received: ', msg);
socket.broadcast.emit('message', msg);
});
});
In my index.html I'm trying to load some js and css files, but I can't seem to load them. The files are inside a js folder which is in the same directory as my app.js and index.html, and I'm trying to load them like so:
<script src="/js/script.js"></script>
If I look at the response from the request in my browser, it's returning the content of index.html.
Again, sorry if this question is silly, but I'm stuck and have no clue where to look.
Thanks!
A web server in node.js does not serve ANY files by default (unlike some other web servers). So, if you want js files to be served, you have to define a web server route that will serve them. The code you show returns index.html for all incoming requests coming into that http server so, it should be no surpise that when a request comes in for /js/script.js, your web server sends out index.html.
A typical framework to use with node.js for web serving is Express and it has express.static() that can be used to define a route that will cover all your static files or all files in a particular directory. You could, of course, code your own static file handling or find some other module to do that also. The point is that you have to write or configure some code to serve your static resource files. That is not done for you automatically by the node.js http server.
you can specify to the server in which folder to look for what
for static files such as css, images you can use
public directory, you can provide your custom directory, but it's better to use public ,same goes for views
always require
const PATH = require('path')
app.use(express.static(PATH.join(__dirname, 'public')));
for template files such as .ejs, .html, .jade use
app.set('views', PATH.join(__dirname, 'views'));

Is it possible to render another express application from express?

Basically what happened was we have an app server that is running express and routes to a bunch of SPAs. This was great but then we wanted to have an app that runs its own node/express script (ghost). I can't figure out how to set the route /ghost to go to ./webapps/ghost/index.js
Is this just not possible?
You need to redirect incoming requests to the ghost express instance. I have done so in my personal site by adding a /blog route to my primary express instance and forwarding any request to it to the ghost expresss instance. Check it out here: https://github.com/evanshortiss/evanshortiss.com/blob/master/server.js
The basic gist is that you do the following:
app.use('/blog', function(req, res, next) {
// Forward this request on...
return next();
}, ghostServer.rootApp); //...but we forward it to a different express instance
If you're running both as separate processes then you could use Apache or nginx to just redirect the requests. If you absolutely must use an express application to forward requests then try the node-http-proxy module.
If you need to proxy from express you could do this using the http-proxy module by Nodejitsu:
var proxy = require('http-proxy').createProxyServer({});
app.use('/blog', function (req, res) {
// You may need to edit req.url (or similar) to strip the /blog part of the url or ghost might not recognise it
proxy.web(req, res, {
target: 'http://127.0.0.1:'+GHOST_PORT
});
});

Resources