Enabling HTTPS on express.js

前端 未结 7 898
栀梦
栀梦 2020-11-22 08:44

I\'m trying to get HTTPS working on express.js for node, and I can\'t figure it out.

This is my app.js code.

var express = require(\'exp         


        
相关标签:
7条回答
  • 2020-11-22 09:24

    Including Points:

    1. SSL setup
      1. In config/local.js
      2. In config/env/production.js

    HTTP and WS handling

    1. The app must run on HTTP in development so we can easily debug our app.
    2. The app must run on HTTPS in production for security concern.
    3. App production HTTP request should always redirect to https.

    SSL configuration

    In Sailsjs there are two ways to configure all the stuff, first is to configure in config folder with each one has their separate files (like database connection regarding settings lies within connections.js ). And second is configure on environment base file structure, each environment files presents in config/env folder and each file contains settings for particular env.

    Sails first looks in config/env folder and then look forward to config/ *.js

    Now lets setup ssl in config/local.js.

    var local = {
       port: process.env.PORT || 1337,
       environment: process.env.NODE_ENV || 'development'
    };
    
    if (process.env.NODE_ENV == 'production') {
        local.ssl = {
            secureProtocol: 'SSLv23_method',
            secureOptions: require('constants').SSL_OP_NO_SSLv3,
            ca: require('fs').readFileSync(__dirname + '/path/to/ca.crt','ascii'),
            key: require('fs').readFileSync(__dirname + '/path/to/jsbot.key','ascii'),
            cert: require('fs').readFileSync(__dirname + '/path/to/jsbot.crt','ascii')
        };
        local.port = 443; // This port should be different than your default port
    }
    
    module.exports = local;
    

    Alternative you can add this in config/env/production.js too. (This snippet also show how to handle multiple CARoot certi)

    Or in production.js

    module.exports = {
        port: 443,
        ssl: {
            secureProtocol: 'SSLv23_method',
            secureOptions: require('constants').SSL_OP_NO_SSLv3,
            ca: [
                require('fs').readFileSync(__dirname + '/path/to/AddTrustExternalCARoot.crt', 'ascii'),
                require('fs').readFileSync(__dirname + '/path/to/COMODORSAAddTrustCA.crt', 'ascii'),
                require('fs').readFileSync(__dirname + '/path/to/COMODORSADomainValidationSecureServerCA.crt', 'ascii')
            ],
            key: require('fs').readFileSync(__dirname + '/path/to/jsbot.key', 'ascii'),
            cert: require('fs').readFileSync(__dirname + '/path/to/jsbot.crt', 'ascii')
        }
    };
    

    http/https & ws/wss redirection

    Here ws is Web Socket and wss represent Secure Web Socket, as we set up ssl then now http and ws both requests become secure and transform to https and wss respectively.

    There are many source from our app will receive request like any blog post, social media post but our server runs only on https so when any request come from http it gives “This site can’t be reached” error in client browser. And we loss our website traffic. So we must redirect http request to https, same rules allow for websocket otherwise socket will fails.

    So we need to run same server on port 80 (http), and divert all request to port 443(https). Sails first compile config/bootstrap.js file before lifting server. Here we can start our express server on port 80.

    In config/bootstrap.js (Create http server and redirect all request to https)

    module.exports.bootstrap = function(cb) {
        var express = require("express"),
            app = express();
    
        app.get('*', function(req, res) {  
            if (req.isSocket) 
                return res.redirect('wss://' + req.headers.host + req.url)  
    
            return res.redirect('https://' + req.headers.host + req.url)  
        }).listen(80);
        cb();
    };
    

    Now you can visit http://www.yourdomain.com, it will redirect to https://www.yourdomain.com

    0 讨论(0)
  • 2020-11-22 09:29

    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.

    0 讨论(0)
  • 2020-11-22 09:30

    Use greenlock-express: Free SSL, Automated HTTPS

    Greenlock handles certificate issuance and renewal (via Let's Encrypt) and http => https redirection, out-of-the box.

    express-app.js:

    var express = require('express');
    var app = express();
    
    app.use('/', function (req, res) {
      res.send({ msg: "Hello, Encrypted World!" })
    });
    
    // DO NOT DO app.listen()
    // Instead export your app:
    module.exports = app;
    

    server.js:

    require('greenlock-express').create({
      // Let's Encrypt v2 is ACME draft 11
      version: 'draft-11'
    , server: 'https://acme-v02.api.letsencrypt.org/directory'
    
      // You MUST change these to valid email and domains
    , email: 'john.doe@example.com'
    , approveDomains: [ 'example.com', 'www.example.com' ]
    , agreeTos: true
    , configDir: "/path/to/project/acme/"
    
    , app: require('./express-app.j')
    
    , communityMember: true // Get notified of important updates
    , telemetry: true       // Contribute telemetry data to the project
    }).listen(80, 443);
    

    Screencast

    Watch the QuickStart demonstration: https://youtu.be/e8vaR4CEZ5s

    For Localhost

    Just answering this ahead-of-time because it's a common follow-up question:

    You can't have SSL certificates on localhost. However, you can use something like Telebit which will allow you to run local apps as real ones.

    You can also use private domains with Greenlock via DNS-01 challenges, which is mentioned in the README along with various plugins which support it.

    Non-standard Ports (i.e. no 80 / 443)

    Read the note above about localhost - you can't use non-standard ports with Let's Encrypt either.

    However, you can expose your internal non-standard ports as external standard ports via port-forward, sni-route, or use something like Telebit that does SNI-routing and port-forwarding / relaying for you.

    You can also use DNS-01 challenges in which case you won't need to expose ports at all and you can also secure domains on private networks this way.

    0 讨论(0)
  • 2020-11-22 09:31

    First, you need to create selfsigned.key and selfsigned.crt files. Go to Create a Self-Signed SSL Certificate Or do following steps.

    Go to the terminal and run the following command.

    sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./selfsigned.key -out selfsigned.crt

    • After that put the following information
    • Country Name (2 letter code) [AU]: US
    • State or Province Name (full name) [Some-State]: NY
    • Locality Name (eg, city) []:NY
    • Organization Name (eg, company) [Internet Widgits Pty Ltd]: xyz (Your - Organization)
    • Organizational Unit Name (eg, section) []: xyz (Your Unit Name)
    • Common Name (e.g. server FQDN or YOUR name) []: www.xyz.com (Your URL)
    • Email Address []: Your email

    After creation adds key & cert file in your code, and pass the options to the server.

    const express = require('express');
    const https = require('https');
    const fs = require('fs');
    const port = 3000;
    
    var key = fs.readFileSync(__dirname + '/../certs/selfsigned.key');
    var cert = fs.readFileSync(__dirname + '/../certs/selfsigned.crt');
    var options = {
      key: key,
      cert: cert
    };
    
    app = express()
    app.get('/', (req, res) => {
       res.send('Now using https..');
    });
    
    var server = https.createServer(options, app);
    
    server.listen(port, () => {
      console.log("server starting on port : " + port)
    });
    
    • Finally run your application using https.

    More information https://github.com/sagardere/set-up-SSL-in-nodejs

    0 讨论(0)
  • 2020-11-22 09:37

    I ran into a similar issue with getting SSL to work on a port other than port 443. In my case I had a bundle certificate as well as a certificate and a key. The bundle certificate is a file that holds multiple certificates, node requires that you break those certificates into separate elements of an array.

        var express = require('express');
        var https = require('https');
        var fs = require('fs');
    
        var options = {
          ca: [fs.readFileSync(PATH_TO_BUNDLE_CERT_1), fs.readFileSync(PATH_TO_BUNDLE_CERT_2)],
          cert: fs.readFileSync(PATH_TO_CERT),
          key: fs.readFileSync(PATH_TO_KEY)
        };
    
        app = express()
    
        app.get('/', function(req,res) {
            res.send('hello');
        });
    
        var server = https.createServer(options, app);
    
        server.listen(8001, function(){
            console.log("server running at https://IP_ADDRESS:8001/")
        });
    

    In app.js you need to specify https and create the server accordingly. Also, make sure that the port you're trying to use is actually allowing inbound traffic.

    0 讨论(0)
  • 2020-11-22 09:39

    In express.js (since version 3) you should use that syntax:

    var fs = require('fs');
    var http = require('http');
    var https = require('https');
    var privateKey  = fs.readFileSync('sslcert/server.key', 'utf8');
    var certificate = fs.readFileSync('sslcert/server.crt', 'utf8');
    
    var credentials = {key: privateKey, cert: certificate};
    var express = require('express');
    var app = express();
    
    // your express configuration here
    
    var httpServer = http.createServer(app);
    var httpsServer = https.createServer(credentials, app);
    
    httpServer.listen(8080);
    httpsServer.listen(8443);
    

    In that way you provide express middleware to the native http/https server

    If you want your app running on ports below 1024, you will need to use sudo command (not recommended) or use a reverse proxy (e.g. nginx, haproxy).

    0 讨论(0)
提交回复
热议问题