Express.js पर HTTPS को सक्षम करना


408

मैं HTTPS को नोड के लिए एक्सप्रेस.जेएस पर काम करने की कोशिश कर रहा हूं, और मैं इसका पता नहीं लगा सकता।

यह मेरा app.jsकोड है।

var express = require('express');
var fs = require('fs');

var privateKey = fs.readFileSync('sslcert/server.key');
var certificate = fs.readFileSync('sslcert/server.crt');

var credentials = {key: privateKey, cert: certificate};


var app = express.createServer(credentials);

app.get('/', function(req,res) {
    res.send('hello');
});

app.listen(8000);

जब मैं इसे चलाता हूं, तो यह केवल HTTP अनुरोधों का जवाब देता है।

मैंने सरल वनीला node.jsआधारित HTTPS ऐप लिखा है :

var   fs = require("fs"),
      http = require("https");

var privateKey = fs.readFileSync('sslcert/server.key').toString();
var certificate = fs.readFileSync('sslcert/server.crt').toString();

var credentials = {key: privateKey, cert: certificate};

var server = http.createServer(credentials,function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
});

server.listen(8000);

और जब मैं इस एप्लिकेशन को चलाने के लिए, यह करता है HTTPS अनुरोध का जवाब। ध्यान दें कि मुझे लगता है कि एफएसआर परिणाम के मामलों में () स्ट्रॉन्ग नहीं है, क्योंकि मैंने दोनों के संयोजन का उपयोग किया है और अभी भी कोई बानो नहीं है।


संपादित करने के लिए संपादित करें:

उत्पादन प्रणालियों के लिए, आप शायद अपने नोडज एप्लिकेशन पर प्रॉक्सी अनुरोधों के लिए नगनेक्स या हाप्रोक्सी का उपयोग कर रहे हैं। आप ssl के अनुरोधों को संभालने के लिए nginx को सेटअप कर सकते हैं और बस अपने नोड app से http बोल सकते हैं। js.

ADD से जोड़ें (4/6/2015)

AWS के उपयोग की प्रणालियों के लिए, आप SSL टर्मिनेशन को संभालने के लिए EC2 इलास्टिक लोड बैलेंसर्स का उपयोग करना बेहतर समझते हैं, और अपने EC2 वेब सर्वरों को नियमित HTTP ट्रैफ़िक की अनुमति देते हैं। आगे की सुरक्षा के लिए, अपने सुरक्षा समूह को ऐसे सेट करें कि केवल ELB को HTTP ट्रैफ़िक को EC2 इंस्टेंसेस पर भेजने की अनुमति है, जो बाहरी अनएन्क्रिप्टेड HTTP ट्रैफ़िक को आपकी मशीनों से टकराने से रोकेगा।



3
यहां संक्षिप्त रूप से उत्तर दिया गया: stackoverflow.com/a/23894573/1882064
arcseldon

AWS पर अंतिम टिप्पणी के बारे में: क्या यह है कि एक सर्वर को https मॉड्यूल के साथ बनाने की आवश्यकता नहीं है? मेरे प्रमाणपत्र जेनकींस के माध्यम से एडब्ल्यूएस में अपलोड किए गए हैं और एआरएन के साथ संभाला गया है; मेरे पास उपयोग के लिए कोई फ़ाइल पथ नहीं है (https विकल्पों में)
sqldoug

@sqldoug मुझे यकीन नहीं है कि मैं इस सवाल को समझता हूं। AWS ELBs को HTTPS कनेक्शन स्वीकार करने और SSL समाप्ति बिंदु के रूप में कार्य करने के लिए कॉन्फ़िगर किया जा सकता है। यही है, वे नियमित HTTP के माध्यम से आपके ऐप सर्वर से बात करते हैं। आमतौर पर एसएसएल के साथ नोडज डील होने का कोई कारण नहीं है, क्योंकि यह सिर्फ अतिरिक्त प्रसंस्करण ओवरहेड है जिसे स्टैक को या तो ईएलबी स्तर पर या एचटीटीपी प्रॉक्सी स्तर पर संभाला जा सकता है।
एलन

धन्यवाद एलन; हाँ, जब से मुझे पता चला है कि NWS को SSL से निपटने की आवश्यकता नहीं है जब AWS ELBs को कॉन्फ़िगर किया जा सकता है।
वर्गल्ड

जवाबों:


671

Express.js में (संस्करण 3 के बाद से) आपको उस वाक्य रचना का उपयोग करना चाहिए:

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);

इस तरह आप देशी http / https सर्वर को एक्सप्रेस मिडलवेयर प्रदान करते हैं

यदि आप चाहते हैं कि आपका ऐप 1024 से नीचे के पोर्ट पर चल रहा हो, तो आपको sudoकमांड (अनुशंसित नहीं) का उपयोग करने की आवश्यकता होगी या रिवर्स प्रॉक्सी का उपयोग करना होगा (जैसे nginx, haproxy)।


2
यहां सभी लिखा है: github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x पैराग्राफ एप्लिकेशन फ़ंक्शन
कोडनेम-

74
ध्यान दें कि यद्यपि 443 HTTPS के लिए डिफ़ॉल्ट पोर्ट है, विकास के दौरान आप शायद 8443 जैसी किसी चीज़ का उपयोग करना चाहते हैं क्योंकि अधिकांश सिस्टम कम-संख्या वाले पोर्ट पर गैर-रूट श्रोताओं को अनुमति नहीं देते हैं।
ebohlman

1
यार, यह जादू की तरह काम करता है :) यह .pem फ़ाइलों को भी स्वीकार करता है, साथ ही इसे वैसे भी करना चाहिए
मार्सेलो टेइसीरा रगार्गी

5
एक्सप्रेस 4 यह काम नहीं करता है, यह काम करता है localhost:80लेकिन नहींhttps://localhost:443
मुहम्मद उमर

13
यदि आप रिवर्स प्रॉक्सी के लिए नेग्नेक्स का उपयोग करने जा रहे हैं, तो नोड के बजाय आपके लिए ssl सीरेट्स को संभाल सकते हैं
Gianfranco P.

48

सबसे पहले, आपको selfsigned.key और selfsigned.crt फ़ाइलों को बनाने की आवश्यकता है । एक स्व-हस्ताक्षरित एसएसएल प्रमाणपत्र बनाने के लिए जाएं या निम्न चरणों का पालन करें।

टर्मिनल पर जाएं और निम्न कमांड चलाएं।

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

  • उसके बाद निम्नलिखित जानकारी डालें
  • देश का नाम (2 अक्षर का कोड) [AU]: यूएस
  • राज्य या प्रांत का नाम (पूरा नाम) [कुछ-राज्य]: एनवाई
  • स्थानीय नाम (जैसे, शहर) []: एनवाई
  • संगठन का नाम (उदाहरण के लिए, कंपनी) [इंटरनेट विजेट्स लिमिटेड Pty]: xyz (आपका - संगठन)
  • संगठनात्मक इकाई का नाम (जैसे, अनुभाग) []: xyz (आपकी इकाई का नाम)
  • सामान्य नाम (जैसे सर्वर FQDN या आपका नाम) []: www.xyz.com (आपका URL)
  • ईमेल पता []: आपका ईमेल

निर्माण के बाद अपने कोड में कुंजी और प्रमाणित फ़ाइल जोड़ता है, और सर्वर में विकल्प पास करता है।

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)
});
  • अंत में https का उपयोग करके अपना एप्लिकेशन चलाएं

अधिक जानकारी https://github.com/sagardere/set-up-SSL-in-nodejs


जब तक आवश्यक न हो, सूदो का उपयोग करना छोड़ देना चाहिए। मैं बस sudo का उपयोग किए बिना इस प्रक्रिया से गुज़रा, लेकिन मुझे मशीन पर व्यवस्थापक के रूप में लॉग इन किया गया था।
झिचोक

27

मैं एसएसएल के साथ पोर्ट 443 के अलावा किसी अन्य पोर्ट पर काम करने के लिए एक समान समस्या में भाग गया। मेरे मामले में मेरे पास एक बंडल सर्टिफिकेट और एक कुंजी भी थी। बंडल सर्टिफिकेट एक फाइल है जिसमें कई सर्टिफिकेट होते हैं, नोड के लिए जरूरी है कि आप उन सर्टिफिकेट को किसी एरे के अलग-अलग तत्वों में तोड़ दें।

    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/")
    });

App.js में आपको https निर्दिष्ट करने और तदनुसार सर्वर बनाने की आवश्यकता है। इसके अलावा, सुनिश्चित करें कि आप जिस पोर्ट का उपयोग करने का प्रयास कर रहे हैं, वह वास्तव में इनबाउंड ट्रैफ़िक की अनुमति दे रहा है।


मेरे पास एक कुंजी है और एक बंडल प्रमाणित है, मुझे यकीन नहीं है कि क्या प्रमाण है: fs.readFileSync (PATH_TO_CERT), बंडल प्रमाणपत्र को "विराम" और कैसे "प्रमाणित" करेगा, प्रमाण में 20+ कुंजियाँ हैं जैसे कि आप मुझसे पूछें :)
मुहम्मद उमर

@MuhammadUmar आपको न तो बंडल को तोड़ना है और न ही यह निर्दिष्ट करना है कि क्या आपके पास एक नहीं है, यदि आपके पास एक बंडल प्रमाणपत्र है यदि लागू हो, और प्रमाणित (सार्वजनिक कुंजी) और कुंजी (निजी कुंजी)
हेडेन थ्रिंग

@eomoto धन्यवाद कली! यह सबसे अच्छा है, आपने पूरी तरह से मेरे द्वारा आवश्यक उदाहरण
हेडन थ्रिंग

11

अंक सहित:

  1. एसएसएल सेटअप
    1. Config / local.js में
    2. Config / env / production.js में

HTTP और WS हैंडलिंग

  1. एप्लिकेशन को विकास में HTTP पर चलना चाहिए ताकि हम आसानी से अपने ऐप को डिबग कर सकें।
  2. सुरक्षा चिंता के लिए उत्पादन में एप्लिकेशन को HTTPS पर चलना चाहिए।
  3. एप्लिकेशन उत्पादन HTTP अनुरोध हमेशा https पर पुनर्निर्देशित होना चाहिए।

एसएसएल कॉन्फ़िगरेशन

Sailsjs में सभी सामानों को कॉन्फ़िगर करने के दो तरीके हैं, पहला है कॉन्फिग फोल्डर में कॉन्फिगर करना हर एक के पास अपनी अलग-अलग फाइल्स (जैसे कनेक्शन कनेक्शन के भीतर डेटाबेस कनेक्शन)। और दूसरा पर्यावरण आधार फ़ाइल संरचना पर कॉन्फ़िगर किया गया है, प्रत्येक पर्यावरण फ़ाइलें config/envफ़ोल्डर में प्रस्तुत करती हैं और प्रत्येक फ़ाइल में विशेष रूप से एनवी के लिए सेटिंग्स होती हैं।

पाल पहले config / env फ़ोल्डर में दिखता है और फिर config / * .js के लिए तत्पर है

अब सेटअप ssl को इन करें 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;

वैकल्पिक आप इसे config / env / production.js में भी जोड़ सकते हैं । (यह स्निपेट यह भी दिखाता है कि मल्टीपल कार्टी सर्टिफिकेट को कैसे संभालना है)

या उत्पादन में। 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 पुनर्निर्देशन

यहाँ ws वेब सॉकेट है और wss सिक्योर वेब सॉकेट का प्रतिनिधित्व करते हैं, जैसा कि हमने ssl तब सेट किया था अब http और ws दोनों अनुरोध सुरक्षित हो गए और क्रमशः https और wss में बदल गए।

हमारे ऐप से कई स्रोत प्राप्त होंगे, जैसे किसी भी ब्लॉग पोस्ट, सोशल मीडिया पोस्ट के लिए अनुरोध प्राप्त होगा, लेकिन हमारा सर्वर केवल https पर चलता है, इसलिए http से आने वाला कोई भी अनुरोध क्लाइंट ब्राउज़र में "इस साइट तक नहीं पहुँचा जा सकता" त्रुटि देता है। और हम अपनी वेबसाइट के ट्रैफिक को नुकसान पहुंचाते हैं। तो हमें http अनुरोध को https में पुनर्निर्देशित करना चाहिए, वही नियम वेबसैट के लिए अनुमति देते हैं अन्यथा सॉकेट विफल हो जाएगा।

इसलिए हमें पोर्ट 80 (http) पर एक ही सर्वर चलाने की जरूरत है, और सभी अनुरोधों को 443 (https) पोर्ट करने के लिए डायवर्ट करें। सर्वर उठाने से पहले पहले config / bootstrap.js फ़ाइल को संकलित करता है। यहां हम पोर्ट 80 पर अपना एक्सप्रेस सर्वर शुरू कर सकते हैं।

Config / bootstrap.js में (http सर्वर बनाएँ और 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();
};

अब आप http://www.yourdomain.com पर जा सकते हैं , यह https://www.yourdomain.com पर रीडायरेक्ट करेगा


8

ग्रीनलॉक-एक्सप्रेस का उपयोग करें: नि: शुल्क एसएसएल, स्वचालित एचटीटीपीएस

Greenlock प्रमाणपत्र जारी करने और नवीकरण (लेट्स एनक्रिप्ट) और http => https पुनर्निर्देशन, आउट-ऑफ-द बॉक्स को संभालता है।

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);

स्क्रीनकास्ट

क्विकस्टार्ट प्रदर्शन देखें: https://youtu.be/e8vaR4CEZ5s

लोकलहोस्ट के लिए

केवल इस समय का उत्तर देना क्योंकि यह एक सामान्य अनुवर्ती प्रश्न है:

आपके पास लोकलहोस्ट पर एसएसएल प्रमाणपत्र नहीं हो सकता है। हालाँकि, आप टेलीबिट जैसी किसी चीज़ का उपयोग कर सकते हैं, जो आपको स्थानीय ऐप्स को वास्तविक के रूप में चलाने की अनुमति देगा।

आप डीएनएस -01 चुनौतियों के माध्यम से ग्रीनलॉक के साथ निजी डोमेन का भी उपयोग कर सकते हैं, जिसका उल्लेख README में विभिन्न प्लगइन्स के साथ किया गया है जो इसका समर्थन करते हैं।

गैर-मानक पोर्ट (अर्थात कोई 80/443)

स्थानीयहोस्ट के बारे में ऊपर दिए गए नोट को पढ़ें - आप गैर-मानक पोर्ट का उपयोग या तो एनक्रिप्ट नहीं कर सकते हैं।

हालाँकि, आप पोर्ट-फ़ॉर्वर्ड, स्नि-मार्ग के माध्यम से अपने आंतरिक गैर-मानक पोर्ट को बाहरी मानक पोर्ट के रूप में उजागर कर सकते हैं, या टेलीबिट जैसी किसी चीज़ का उपयोग कर सकते हैं जो आपके लिए SNI-रूटिंग और पोर्ट-फ़ॉरवर्डिंग / रिलेइंग करता है।

आप DNS-01 चुनौतियों का भी उपयोग कर सकते हैं जिस स्थिति में आपको बंदरगाहों को उजागर करने की आवश्यकता नहीं होगी और आप इस तरह से निजी नेटवर्क पर भी डोमेन सुरक्षित कर सकते हैं।


"आपके पास लोकलहोस्ट पर एसएसएल प्रमाणपत्र नहीं हो सकता है।" - मेरे पास SSL है जो लोकलहोस्ट पर मेरे रिएक्ट ऐप पर काम कर रहा है। एक्सप्रेस में काम करने के तरीके की तलाश में यहां आया था। रिएक्ट मेरा फ्रंटेंड है, और एक्सप्रेस मेरा बैकएंड है। स्ट्राइप के लिए काम करने की आवश्यकता है, क्योंकि मेरी पोस्ट स्ट्राइप के लिए एसएसएल में होनी चाहिए। स्पष्ट होना चाहिए, लेकिन लोकलहोस्ट में मैं परीक्षण कर रहा हूं, और सर्वर पर यह उत्पादन होगा।
ताउम्र

सुधार: "आपके पास लोकलहोस्ट पर मान्य एसएसएल प्रमाणपत्र नहीं हो सकते हैं "।
CoolAJ86

6

इस तरह से यह मेरे लिए काम कर रहा है। उपयोग किया गया पुनर्निर्देशन सभी सामान्य http को भी पुनर्निर्देशित करेगा।

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const app = express();
var request = require('request');
//For https
const https = require('https');
var fs = require('fs');
var options = {
  key: fs.readFileSync('certificates/private.key'),
  cert: fs.readFileSync('certificates/certificate.crt'),
  ca: fs.readFileSync('certificates/ca_bundle.crt')
};

// API file for interacting with MongoDB
const api = require('./server/routes/api');

// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// Angular DIST output folder
app.use(express.static(path.join(__dirname, 'dist')));

// API location
app.use('/api', api);

// Send all other requests to the Angular app
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist/index.html'));
});
app.use(function(req,resp,next){
  if (req.headers['x-forwarded-proto'] == 'http') {
      return resp.redirect(301, 'https://' + req.headers.host + '/');
  } else {
      return next();
  }
});


http.createServer(app).listen(80)
https.createServer(options, app).listen(443);

0

यह एक्सप्रेस 4.0 के लिए मेरा काम कोड है

एक्सप्रेस 4.0 3.0 और अन्य से बहुत अलग है।

4.0 आपके पास / बिन / www फ़ाइल है, जिसे आप यहां https जोड़ने जा रहे हैं।

"npm start" मानक तरीका है जिससे आप एक्सप्रेस 4.0 सर्वर शुरू करते हैं।

readFileSync () फ़ंक्शन को वर्तमान निर्देशिका प्राप्त करने के लिए __dirname का उपयोग करना चाहिए

जबकि () उपयोग की आवश्यकता होती है । वर्तमान निर्देशिका को देखें।

सबसे पहले आप Private.key और public.cert फाइल को / bin फोल्डर के नीचे रखते हैं, यह WWW फाइल की तरह ही फोल्डर है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.