[node.js] express.js에서 HTTPS 사용
노드의 express.js에서 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 요청에 응답합니다. 나는 fs 결과의 toString ()이 중요하지 않다는 것을 명심하십시오. 내가 부에노를 사용하지 않고 여전히 둘 다의 조합을 사용했기 때문입니다.
추가 편집 :
프로덕션 시스템의 경우 Nginx 또는 HAProxy를 사용하여 nodejs 앱에 요청을 프록시하는 것이 좋습니다. nginx를 설정하여 SSL 요청을 처리하고 노드 app.js에 http를 말하면됩니다.
추가 편집 (2015 년 4 월 6 일)
AWS를 사용하는 시스템의 경우 EC2 Elastic Load Balancer를 사용하여 SSL 종료를 처리하고 EC2 웹 서버에 대한 정기적 인 HTTP 트래픽을 허용하는 것이 좋습니다. 보안을 강화하려면 ELB 만 EC2 인스턴스로 HTTP 트래픽을 보낼 수 있도록 보안 그룹을 설정하십시오. 그러면 암호화되지 않은 외부 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 서버에 빠른 미들웨어를 제공합니다
1024 미만의 포트에서 앱을 실행하려면 sudo
명령 을 사용 하거나 (권장하지 않음) 리버스 프록시 (예 : nginx, haproxy)를 사용해야합니다.
답변
먼저 selfsigned.key 및 selfsigned.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를 사용하여 애플리케이션을 실행하십시오 .
답변
포트 443 이외의 포트에서 SSL을 작동시키는 것과 비슷한 문제가 발생했습니다. 제 경우에는 인증서와 키뿐만 아니라 번들 인증서도있었습니다. 번들 인증서는 여러 인증서를 보유하는 파일이며 노드에서는 해당 인증서를 배열의 개별 요소로 분리해야합니다.
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를 지정하고 그에 따라 서버를 작성해야합니다. 또한 사용하려는 포트가 실제로 인바운드 트래픽을 허용하는지 확인하십시오.
답변
포인트 포함 :
- SSL 설정
- config / local.js에서
- config / env / production.js에서
HTTP 및 WS 처리
- 앱을 개발할 때 HTTP에서 실행해야 앱을 쉽게 디버깅 할 수 있습니다.
- 보안 문제를 위해 프로덕션 환경에서 앱을 HTTPS에서 실행해야합니다.
- 앱 프로덕션 HTTP 요청은 항상 https로 리디렉션되어야합니다.
SSL 구성
Sailsjs에는 모든 것을 구성하는 두 가지 방법이 있습니다. 먼저 구성 폴더에서 각 파일마다 별도의 파일이 있습니다 (설정에 관한 데이터베이스 연결은 connections.js 내에 있음). 두 번째는 환경 기반 파일 구조에서 구성되며 각 환경 파일은 config/env
폴더에 표시되며 각 파일에는 특정 환경에 대한 설정이 포함됩니다.
Sails는 먼저 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 에서도 이를 추가 할 수 있습니다 . (이 발췌문은 여러 CARoot certi를 처리하는 방법도 보여줍니다)
또는 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 리디렉션
여기서 ws는 Web Socket이고 wss는 Secure Web Socket을 나타냅니다. ssl을 설정하면 이제 http와 ws는 두 요청이 모두 안전 해지고 https와 wss로 각각 변환됩니다.
우리의 응용 프로그램에서 많은 소스가 블로그 게시물, 소셜 미디어 게시물과 같은 요청을 수신하지만 서버는 https에서만 실행되므로 http에서 온 요청은 클라이언트 브라우저에서 “이 사이트에 도달 할 수 없습니다”오류가 발생합니다. 그리고 우리는 웹 사이트 트래픽을 잃습니다. 따라서 우리는 http 요청을 https로 리디렉션해야합니다. 동일한 규칙이 websocket을 허용하면 소켓이 실패합니다.
따라서 포트 80 (http)에서 동일한 서버를 실행하고 모든 요청을 포트 443 (https)으로 전환해야합니다. Sails는 먼저 서버를 들어 올리기 전에 config / bootstrap.js 파일을 컴파일합니다. 여기에서 포트 80에서 Express 서버를 시작할 수 있습니다.
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으로 리디렉션됩니다.
답변
greenlock-express 사용 : 무료 SSL, 자동화 된 HTTPS
그린 락 은 인증서 발급 및 갱신 (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);
스크린 캐스트
빠른 시작 데모를보십시오 : https://youtu.be/e8vaR4CEZ5s
로컬 호스트
이 후속 답변은 일반적인 후속 질문이므로 다음과 같이 답변하십시오.
localhost에 SSL 인증서를 가질 수 없습니다. 그러나 Telebit 과 같은 것을 사용하면 로컬 앱을 실제 앱으로 실행할 수 있습니다.
또한 README에 언급 된 DNS-01 문제를 통해 Greenlock과 함께 개인 도메인을 지원할 수있는 다양한 플러그인을 사용할 수 있습니다.
비표준 포트 (즉, 80/443 없음)
localhost에 대한 위의 참고 사항을 읽으십시오. Let ‘s Encrypt와 함께 비표준 포트를 사용할 수 없습니다.
그러나 포트 전달, 스니 라우트를 통해 내부 비표준 포트를 외부 표준 포트로 노출하거나 SNI 라우팅 및 포트 전달 / 릴레이를 수행하는 Telebit와 같은 것을 사용할 수 있습니다.
또한 DNS-01 챌린지를 사용하면 포트를 전혀 노출 할 필요가없고 개인 네트워크의 도메인을 이런 방식으로 보호 할 수도 있습니다.
답변
이것이 나를 위해 일하는 방법입니다. 사용 된 리디렉션은 모든 일반 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);
답변
이것은 Express 4.0의 작업 코드 입니다. .
express 4.0은 3.0과는 매우 다릅니다.
4.0 / bin / www 파일이 있으며 여기에 https를 추가합니다.
“npm start”는 Express 4.0 서버를 시작하는 표준 방법입니다.
readFileSync () 함수는 __dirname을 사용해야합니다 get current directory를
require () use ./ 는 현재 디렉토리를 참조하십시오.
먼저 private.key 및 public.cert 파일을 / bin 폴더에 넣습니다 . WWW 파일과 같은 폴더 입니다.