Express (node.js) using HTTPS and HTTP

13,719

Solution 1

Simply pass your app (which is really a request handler function) to the createServer of http and https.

var express = require('express')
    , http = require('http')
    , https = require('https')
    , app = express();

http.createServer(app);
https.createServer({ ... }, app);

Both HTTP and HTTPS requests get routed through the same Express app. In a route handler, to check whether a request was made over https, use req.secure.

app.get('/route', function(req, res) {
    if (req.secure) {
        ...
    } else {
        res.redirect(301, 'https://example.com/route');
    }
});

As a side note, modern wisdom considers mixed http/https sites insecure. You may protect the user's password by requiring them to log in over SSL, but then switching back to http for subsequent requests makes it trivial for an attacker to steal a user's login cookie.

Consider making all requests by logged-in users over SSL.

Solution 2

Try this approach.Create two express request handlers(app_http and app_https).

Pass app_http as request handler while creating http server(http.createServer(app_http)).

Pass app_https as request handler while createing https server (https.createServer(options,app_https)).

var express = require('express'),
    http = require('http'),
    https = require('https');

var app_http = express(); // this one to handle http request

var app_https = express(); // this to handle httpS requests.


app_https.get('/connect', function(req, res){
 // Must be on HTTPS, if not redirect to HTTPS
});

app_https.post('/connect', function(req, res){
  // Must be on HTTPS
});

app_http.get('/', function(req, res){
 // Must be on HTTP
});

app_http.get('/build', function(req, res){
 // Must be on HTTP
});

    //call here http.createServer &  https.createServer with needed details.

Solution 3

const express = require('express');
const app = express();
const fs = require('fs');
const options = {
    key:fs.readFileSync('./ssl/privkey.pem'),
    cert:fs.readFileSync('./ssl/allchange.pem')
};
const https = require('https').createServer(options,app);
const http = require('http').createServer(app);
app.get('/',(req,res) => {
    (req.protocol == 'http') ? res.redirect('https://www.pkred.com/') : // code
        // More code
        // End code ;
}
app.get('/:id',(req,res) => {
    (req.protocol == 'http') ? res.redirect(`https://www.pkred.com/${req.params.id}`) : // code
        // More code
        // End code ;
}
http.listen(8080,() => console.log('PORT :: 8080'));
https.listen(4433,() => console.log('PORT :: 4433'));
Share:
13,719
George Reith
Author by

George Reith

Updated on July 19, 2022

Comments

  • George Reith
    George Reith almost 2 years

    I am using the express (3.0) framework on node.js to route my application.

    Most of my application uses the http protocol however there is one specific route I want to serve via https only. This is the part of my API which is responsible for registering and authenticating users.

    for example:

    app.get('/connect', function(req, res){
     // Must be on HTTPS, if not redirect to HTTPS
    });
    
    app.post('/connect', function(req, res){
      // Must be on HTTPS
    });
    
    app.get('/', function(req, res){
     // Must be on HTTP
    });
    
    app.get('/build', function(req, res){
     // Must be on HTTP
    });
    

    How does one facilitate using both within the same application? I am struggling to find any examples of this in the wild.

  • George Reith
    George Reith over 10 years
    Thanks but I have a load of middleware, do I really have to specify it all twice just to listen to handle TLS requests?
  • Chandu
    Chandu over 10 years
    Yes we need to load the middleware for each of them . I would do the following to ease the task, Write a utility that takes app as parameter and loads the middleware. function loadMiddleware(app){app.use(),....} . If you have a function like this then its all about making two calls , one with app_http and the other with app_https. Hope this helps
  • Chandu
    Chandu over 10 years
    In the case where you create two express request handlers, the answer i suggested , you will need to load middleware for each of them. But if you chose to use the same app,check if request is over ssl, then you need only once.
  • Chandu
    Chandu over 10 years
    In this case how do you handle the case where you need different middleware stacks for secure and non-secure requests ? Like for non-secure i do not need session management overhead but for secure i need.
  • George Reith
    George Reith over 10 years
    Thanks this is very useful, the only thing that is stopping me from using HTTPS everywhere is the overhead, this is an action intensive web app making a large number of API calls and something like this becomes very noticeable. I think if the user has compromised their own system with such software then that is something I am not liable to defend them from.
  • josh3736
    josh3736 over 10 years
    @GeorgeReith: Have you actually measured overhead? On a modern systems, the overhead of SSL is < 1% of CPU. In fact, with optimizations like SPDY, you might find that a SSL-secured connection actually performs better than plain HTTP. I'd be willing to wager that in reality, you'd be unable to notice any negative difference in performance. Also, session hijacking (stealing login cookies) is a passive network attack; it has nothing to do with a compromised user machine. (This is precisely why Facebook is all HTTPS now.) In 2013, there's no excuse for not using all SSL (and HSTS).
  • George Reith
    George Reith over 10 years
    @josh3736 Nope I guess I am reading old information about SSL then. I will start of by using both and will benchmark it and see if the SSL version is acceptable if so I'll use it concurrently. Thanks for the info, you've given me a lot to ponder.
  • thisissami
    thisissami about 10 years
    @GeorgeReith - did you ever do the benchmarking and see whether or not there is a difference in performance between HTTPS all the way or a mix/match of the two? I'm in the same boat as you now and would love to know what you've found!
  • Bacon Brad
    Bacon Brad about 8 years
    Old post. But for anyone else reading this is much bigger than an overhead issue. Using HTTPS for authentication and then HTTP for all other data transmission is like putting up a gate but not bothering with the fence. The gate is locked but you can walk right around it and take what you want. The only thing you are protecting is the password to the data you wish to protect. But the the data remains out there in the open. Making your implementation moot and giving you a false sense of security. Don't do it.