programing

express.js에서 HTTPS 사용

skycolor 2023. 5. 22. 20:54
반응형

express.js에서 HTTPS 사용

노드에 대해 HTTPS에서 express.js를 작업하려고 하는데 알 수가 없습니다.

은 나의 이것나입니다.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 요청에 응답합니다.참고로 저는 fs 결과의 toString()은 중요하지 않다고 생각합니다. 왜냐하면 저는 둘 다와 여전히 noesbueno의 조합을 사용했기 때문입니다.


추가할 편집 대상:

프로덕션 시스템의 경우 Nginx 또는 HAProxy를 사용하여 요청을 nodejs 앱으로 프록시 처리하는 것이 좋습니다.nginx가 ssl 요청을 처리하도록 설정하고 노드 app.js에 http만 말할 수 있습니다.

편집 대상 추가(2015년 4월 6일)

AWS를 사용하는 시스템의 경우, EC2 Elastic Load Balancers를 사용하여 SSL 종료를 처리하고 EC2 웹 서버에 대한 정기적인 HTTP 트래픽을 허용하는 것이 좋습니다.보안을 강화하려면 ELB만 HTTP 트래픽을 EC2 인스턴스로 보낼 수 있도록 보안 그룹을 설정하면 암호화되지 않은 외부 HTTP 트래픽이 컴퓨터에 도달하지 않습니다.


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 서버에 고속 미들웨어를 제공합니다.

포트를 사용해야 합니다.sudo명령(권장하지 않음) 또는 역방향 프록시(예: nginx, haproxy)를 사용합니다.

먼저 자체 서명을 생성해야 합니다.자체 서명된 .crt 파일.자체 서명 SSL 인증서 만들기로 이동하거나 다음 단계를 수행합니다.

터미널로 이동하여 다음 명령을 실행합니다.

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

  • 그 후에 다음 정보를 입력합니다.
  • 국가 이름(2글자 코드) [AU]: 미국
  • 시/도 이름(전체 이름) [일부 주]:NY
  • 지역 이름(예: 도시) []:NY
  • 조직 이름(예: 회사) [Internet Widgits Pty Ltd]: 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

SSL을 포트 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를 지정하고 그에 따라 서버를 만들어야 합니다.또한 사용하려는 포트가 실제로 인바운드 트래픽을 허용하는지 확인합니다.

포인트 포함:

  1. SSL 정
    1. in config/local.js
    2. config/env/production.js에서

HTTP 및 WS 처리

  1. 개발 중인 HTTP에서 앱을 실행해야 앱을 쉽게 디버그할 수 있습니다.
  2. 보안 문제로 인해 운영 중인 HTTPS에서 앱을 실행해야 합니다.
  3. 앱 제작 HTTP 요청은 항상 https로 리디렉션해야 합니다.

SSL 구성

Sailsjs에서는 모든 것을 구성하는 두 가지 방법이 있습니다. 첫 번째 방법은 config 폴더에서 각각 개별 파일을 가지고 구성하는 것입니다(예: connections.js 내의 설정과 관련된 데이터베이스 연결).구조에 대해 으로, 각은 " " " " " " " " " " " 에 있습니다.config/env폴더 및 각 파일에는 특정 환경에 대한 설정이 포함되어 있습니다.

Sails는 먼저 config/env 폴더를 찾은 다음 config/ *.js를 기대합니다.

"ssl"에서 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에도 추가할 수 있습니다. (이 스니펫은 여러 개의 CARoot certi를 처리하는 방법도 보여줍니다.)

또는 프로덕션에서.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/syslog 및 ws/wss 리디렉션

다음은 Web Socket이고 wss는 Secure Web Socket을 나타냅니다. ssl을 설정하면 http와 wss 요청이 모두 보안이 되고 https와 wss로 각각 변환됩니다.

블로그 게시물, 소셜 미디어 게시물처럼 우리 앱에서 요청을 받을 수 있는 소스가 많지만 우리 서버는 https에서만 실행되므로 http에서 요청이 오면 클라이언트 브라우저에서 "이 사이트에 도달할 수 없습니다" 오류를 표시합니다.그리고 우리는 웹사이트 트래픽을 잃게 됩니다.따라서 http 요청을 https로 리디렉션해야 합니다. 웹 소켓에 동일한 규칙이 허용되지 않으면 소켓이 실패합니다.

따라서 포트 80(http)에서 동일한 서버를 실행하고 모든 요청을 포트 443(https)으로 전환해야 합니다.서버를 들어올리기 전에 먼저 컴파일 구성/bootstrap.js 파일을 이동합니다.여기서 포트 80에서 고속 서버를 시작할 수 있습니다.

in 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 으로 리디렉션됩니다.

이것이 저에게 효과가 있는 방법입니다.사용된 리디렉션은 모든 일반 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);

이 답변은 Setthase와 매우 유사하지만 LetsEncrypt(Ubuntu)대한 답변입니다.

// Dependencies
const fs = require('fs');
const http = require('http');
const https = require('https');
const express = require('express');

const app = express();

// Certificate
const privateKey = fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/cert.pem', 'utf8');
const ca = fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/chain.pem', 'utf8');

const credentials = {
    key: privateKey,
    cert: certificate,
    ca: ca
};

app.use((req, res) => {
    res.send('Hello there !');
});

// Starting both http & https servers
const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);

httpServer.listen(80, () => {
    console.log('HTTP Server running on port 80');
});

httpsServer.listen(443, () => {
    console.log('HTTPS Server running on port 443');
});

다음과 같은 메시지가 표시될 수 있습니다. EACCES: 권한이 거부되었습니다. '/etc/letsencrypt/live/yourdeomain.com/privkey.pem' '을 엽니다.

여기에 대한 대답이 있습니다. "Error: EACCES: 권한이 거부되었습니다. '/etc/letsencrypt/live/domain.net/privkey.pem' '로 SSL을 암호화할 없습니다.

나에게 효과가 있었던 것은 ubuntu ssh 터미널 사용자 가져오기입니다.whoami

// Create group with root and nodeuser as members
$ sudo addgroup nodecert
$ sudo adduser ubuntu nodecert
$ sudo adduser root nodecert

// Make the relevant letsencrypt folders owned by said group.
$ sudo chgrp -R nodecert /etc/letsencrypt/live
$ sudo chgrp -R nodecert /etc/letsencrypt/archive

// Allow group to open relevant folders
$ sudo chmod -R 750 /etc/letsencrypt/live
$ sudo chmod -R 750 /etc/letsencrypt/archive

sudo reboot

greenlock-express 사용:무료 SSL, 자동화된 HTT

Greenlock은 Let's Encrypt를 통해 인증서 발급 및 갱신을 처리하고 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);

스크린캐스트

QuickStart 데모 보기: https://youtu.be/e8vaR4CEZ5s

로컬 호스트의 경우

일반적인 후속 질문이기 때문에 미리 답변하는 것뿐입니다.

로컬 호스트에는 SSL 인증서를 사용할 수 없습니다.하지만 텔레비트와 같은 것을 사용하면 로컬 앱을 실제 앱으로 실행할 수 있습니다.

또한 DNS-01 챌린지를 통해 Greenlock과 함께 개인 도메인을 사용할 수 있으며, 이는 README에서 이를 지원하는 다양한 플러그인과 함께 언급됩니다.

비표준 포트(예: no 80/443)

localhost에 대한 위의 참고 사항을 읽어 보십시오. 암호화를 사용하여 비표준 포트를 사용할 수도 없습니다.

그러나 포트 포워드, Sni-route를 통해 내부 비표준 포트를 외부 표준 포트로 노출하거나 SNI 라우팅 및 포트 포워딩/릴레이를 수행하는 Telebit과 같은 기능을 사용할 수 있습니다.

DNS-01 문제를 사용할 수도 있습니다. 이 경우 포트를 노출할 필요가 전혀 없으며 이러한 방식으로 전용 네트워크의 도메인을 보호할 수도 있습니다.

다음을 사용하여 자체 서명된 인증서를 생성할 수도 있습니다.

아래 코드에서는 시작 시 새 인증서가 생성됩니다. 즉, 서버를 다시 시작할 때마다 새 인증서를 받게 됩니다.

const https = require('https')
const express = require('express')
const forge = require('node-forge')


;(function main() {
  const server = https.createServer(
    generateX509Certificate([
      { type: 6, value: 'http://localhost' },
      { type: 7, ip: '127.0.0.1' }
    ]), 
    makeExpressApp()
  )
  server.listen(8443, () => {
    console.log('Listening on https://localhost:8443/')
  })
})()


function generateX509Certificate(altNames) {
  const issuer = [
    { name: 'commonName', value: 'example.com' },
    { name: 'organizationName', value: 'E Corp' },
    { name: 'organizationalUnitName', value: 'Washington Township Plant' }
  ]
  const certificateExtensions = [
    { name: 'basicConstraints', cA: true },
    { name: 'keyUsage', keyCertSign: true, digitalSignature: true, nonRepudiation: true, keyEncipherment: true, dataEncipherment: true },
    { name: 'extKeyUsage', serverAuth: true, clientAuth: true, codeSigning: true, emailProtection: true, timeStamping: true },
    { name: 'nsCertType', client: true, server: true, email: true, objsign: true, sslCA: true, emailCA: true, objCA: true },
    { name: 'subjectAltName', altNames },
    { name: 'subjectKeyIdentifier' }
  ]
  const keys = forge.pki.rsa.generateKeyPair(2048)
  const cert = forge.pki.createCertificate()
  cert.validity.notBefore = new Date()
  cert.validity.notAfter = new Date()
  cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1)
  cert.publicKey = keys.publicKey
  cert.setSubject(issuer)
  cert.setIssuer(issuer)
  cert.setExtensions(certificateExtensions)
  cert.sign(keys.privateKey)
  return {
    key: forge.pki.privateKeyToPem(keys.privateKey),
    cert: forge.pki.certificateToPem(cert)
  }
}


function makeExpressApp() {
  const app = express()
  app.get('/', (req, res) => {
    res.json({ message: 'Hello, friend' })
  })
  return app
}

자격 증명에 있는 PEM 암호 구문을 잊지 마십시오!

하여 자격 할 때(OpenSSL을 마십시오.)-sha256플래그) :

OpenSSL> req -x509 -sha256 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
Generating a RSA private key

writing new private key to 'key.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

JS/TS 코드:

const credentials = {key: privateKey, cert: certificate, passphrase: 'YOUR passphrase'};

언급

이것은 익스프레스 4.0대한 나의 작업 코드입니다.

express 4.0은 3.0 및 다른 것들과 매우 다릅니다.

4.0 여기에 https를 추가할 /bin/www 파일이 있습니다.

"npm start"는 express 4.0 서버를 시작하는 표준 방법입니다.

readFileSync() 함수는 __dirname get current 디렉토리를 사용해야 합니다.

required는 ./ 현재 디렉토리를 참조하십시오.

먼저 당신은 개인적인 것을./bin 폴더의 key and public.cert 파일, WWW 파일과 동일한 폴더입니다..

언급URL : https://stackoverflow.com/questions/11744975/enabling-https-on-express-js

반응형