노드, Express, SSL 인증서: HTTPS 서버를 5단계로 시작하여 처음부터 실행합니다.

Node, Express, SSL Certificate: Run HTTPS Server from scratch in 5 steps


한 고객을 위해 웹 응용 프로그램을 작성하는 데 어려움을 겪었을 때, 나는 이 강좌에 관한 글을 쓰기로 결정했다.이것은 간단한 네트워크 도표이지만, 그것은 전보 로봇에서 데이터를 수집한다.MongoDB에 데이터를 저장하고 데이터를 얻기 위해 빠른 API를 준비했지만 얻는 과정에서 많은 문제가 발생했고 SSL 인증서가 그 중 하나입니다.
따라서 이 강좌에서 제 잘못과 문제, 그리고 해결 방안을 소개하겠습니다. 만약에 간단한 버전으로 넘어가고 싶다면 continue from here할 수 있습니다.
본문에서 나는 몬godB와 관련된 코드나 문제를 언급하지 않을 것이다.

1. Express를 사용하여 내 기본 API 서버 만들기


내 프로젝트에서 프로젝트 폴더를 만든 후 npm 또는 yarn 환경을 만드는 것을 더 좋아한다.
그래서 다음 명령을 사용했습니다.
mkdir my-project && cd my-project
yarn init
Enter 이후에 스팸메일yarn init을 보내고 기본 설정으로 프로젝트 환경을 만듭니다.
(만약 그것을 사용하는 데 장애가 없다면, 나는 yarn가 아니라 npm를 더 좋아한다.
그런 다음 express를 프로젝트에 설치하고 로컬에 설치합니다.
yarn add express
다음을 사용할 수 있습니다.
npm install express
그런 다음 단일 소스 파일index.js을 만들고 다음 행을 삽입했습니다.
// import express
const express = require('express');

// create new express app and assign it to `app` constant
const app = express();

// server port configuration
const PORT = 8080;

// create a route for the app
app.get('/', (req, res) => {
  res.send('Hello dev.to!');
});

// server starts listening the `PORT`
app.listen(PORT, () => {
  console.log(`Server running at: http://localhost:${PORT}/`);
});
지금까지 나는 express 패키지를 가져와 실례를 만들고 그것을 app에 분배했다.myPORT 변수를 설정하고 내 API 서버에서 endpoint 처리를 위한 루트를 만들고 app.list(PORT, callback()) 방법을 호출해서 지정한 포트에서 서버를 시작합니다.
내 터미널로 돌아가 프로젝트 디렉토리에서 다음 명령을 실행합니다.
node index.js
다음과 같이 내 서버를 시작하고 콘솔에 로그인합니다.
Server running at http://localhost:8080/
그런 다음 브라우저로 전환하여 http://localhost:8080/로 이동하면 다음 페이지가 나타납니다.

지금까지 줄곧 괜찮았다.내 프로그램이 내 포트를 정확하게 정탐하고 있다.
이후에 나는 나의 초기 시험 작업을 테스트했고, 내가 더 많은 단점을 처리할 수 있는지 테스트하고 싶었다.그래서 나는 방금 코드에 다른 것을 추가했다route.
app.get('/omergulen', (req, res) => {
  res.send('Hello Omer! Welcome to dev.to!');
});
나는 브라우저에 /omergulenendpoint를 입력해야만 그것이 작용하기를 바란다.
그래서 저는 Control+C로 실행 중인 서버를 멈추고 다시 시작합니다. 왜냐하면 열 리셋은 제가 프로그램을 실행하는 고유한 방식이 아니기 때문입니다.내 브라우저로 전환하고 http://localhost:8080/omergulen 방문했습니다. 실행 중입니다. 다시 방문했는지 확인하십시오. http://localhost:8080/ 도 예상대로 작동합니다.

2. 왜 그리고 어떻게 Express에서 중간부품을 사용합니까?


첫 번째 API 서버를 배치한 후 웹 응용 프로그램 프로젝트로 전환하고 API 노드에 요청서를 보냈습니다.
fetch('MY_API_URL')
  .then(function (response) {
    console.log(response);
    return response.json();
  })
  .then(...);
내 DOM에는 아무 일도 없었지만 콘솔 소식은 우울했다.
Access to fetch at 'MY_API_URL' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

App.js:34 Cross-Origin Read Blocking (CORB) blocked cross-origin response MY_API_URL with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.
빠른 연구를 한 후에 나는 CORS Policy에 따라 나의 API 서버를 설정해야 한다는 것을 깨달았다.
먼저 요청에 추가mode: 'cors':
fetch('MY_API_URL', {
  mode: 'cors'
})
.then(function (response) {
  console.log(response);
  return response.json();
})
.then(...);
이것은 나의 문제에 아무런 소용이 없다.그리고 나서, 나는 내 cors 중간부품을 API 서버에 추가했는데, 실제로는 두 줄의 코드만 있었다.cors 구성 요소를 설치한 후 다음을 수행합니다.
yarn add cors
방금 코드에 다음 행을 추가했습니다.
// import `cors` package
const cors = require('cors');

// use middleware
app.use(cors());
이 설정을 사용해서 실행한 후에, 나의 문제는 잠시 해결되었다.

3. Express API 서버를 HTTPS 서비스로 사용하는 방법


배포를 위해 내 프로젝트를 내 VPS로 이동하고 내 도메인my_api_url을 이 VPS로 리디렉션합니다.이런 방식을 통해 나는 나의 서버 IP에 작은 추상층을 추가했다. 그리고 나는 어느 곳에서든 나의 IP를 입력할 필요가 없고 나의 영역과 화려한 자역을 사용할 수 있다. 예를 들어api.omergulen.com.
이 단계에서, 나는 우선 HTTP 인증이 없는 상황에서 그것을 배치하려고 시도했다.
[blocked] The page at 'https://my_web_app'  was loaded over HTTPS but ran insecure content from 'http://my_api_url': this content should also be loaded over HTTPS.
그러나 내 웹 서버는Firebase 호스트의 서버로https로 사용되며HTTPS to HTTP로부터 요청을 보내는 것을 Mixed Content라고 부른다.허락할 수 없습니다.
그래서 나는 단지 s를 URL의 첫머리에 놓을 뿐이다.https://my_api_url 네가 짐작할 수 있듯이 그것도 작용하지 않는다.
GET https://my_api_url net::ERR_SSL_PROTOCOL_ERROR
그리고 중점적으로 연구한 후에 저는 인증서 발급 기구를 갖춘 인증서를 만들어야 한다는 것을 깨달았습니다.많은 증서 발급 기관들이 보수를 받았지만 Let's Encrypt 받지 못했다.
Let's Encrypt는 무료이며 자동적이며 개방적인 인증 기관입니다.
서버에 셸 접근 권한이 있다면 certbot 을 사용하십시오.certbot 웹 사이트에서 다음을 선택했습니다.
나의 HTTP 사이트는 None of the above에서 운행Ubuntu 16.04 (xenial)하는데 이것은 나의 상황과 일치한다.
시작하기 전에 그들은 네가 확보하기를 바란다.
  • 명령행의 편안함
  • 와 HTTP 사이트(내 예는 API 서버)
  • online
  • 및 HTTP 포트80
  • 관리server
  • 액세스 가능SSH
  • 지원sudo
  • 그런 다음 다음 다음 절차를 따르십시오.

    1. SSH 서버 접속


    SSH를 sudo 권한이 있는 사용자로 HTTP 웹 사이트를 실행하는 서버에 연결합니다.

    2. Certbot PPA 추가


    Certbot PPA를 저장소 목록에 추가해야 합니다.이렇게 하려면 컴퓨터의 명령줄에서 다음 명령을 실행합니다.
    sudo apt-get update &&
    sudo apt-get install software-properties-common &&
    sudo add-apt-repository universe &&
    sudo add-apt-repository ppa:certbot/certbot &&
    sudo apt-get update
    

    3. Certbot 설치


    컴퓨터의 명령줄에서 이 명령을 실행하여 Certbot을 설치합니다.
    sudo apt-get install certbot
    

    4. Certbot 실행 방법 선택


    당신은 당신의 사이트를 잠시 정지할 수 있습니까?
    네, 현재 이 컴퓨터에서 웹 서버가 실행되고 있지 않습니다.
    웹 서버를 정지하고 인증서를 얻기 위해 이 명령을 실행합니다.Certbot은 사용자의 시스템에서 웹 서버를 임시로 시작합니다.
    sudo certbot certonly --standalone
    
    아니오, 네트워크 서버를 유지해야 합니다.
    웹 서버가 포트 80을 사용하고 있고 Certbot이 실행될 때 멈추고 싶지 않으면 이 명령을 실행하고 터미널의 설명에 따라 실행하십시오.
    sudo certbot certonly --webroot
    
    이 단계에서 터미널에 영역을 삽입해야 합니다. 예를 들어 dev.to.그런 다음 웹 서버를 검사하고 작성할 특정 파일을 찾습니다. 성공하면 다음과 같이 인쇄해야 합니다.
    Performing the following challenges:
    http-01 challenge for my_api_url
    Waiting for verification...
    Cleaning up challenges
    
    IMPORTANT NOTES:
     - Congratulations! Your certificate and chain have been saved at:
       /etc/letsencrypt/live/my_api_url/fullchain.pem
       Your key file has been saved at:
       /etc/letsencrypt/live/my_api_url/privkey.pem
       Your cert will expire on 2020-04-01. To obtain a new or tweaked
       version of this certificate in the future, simply run certbot
       again. To non-interactively renew *all* of your certificates, run
       "certbot renew"
     - If you like Certbot, please consider supporting our work by:
    
       Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
       Donating to EFF:                    https://eff.org/donate-le
    
    중요 팁:
    웹 루트 플러그인을 사용하려면 디렉터리에 숨겨진 파일을 제공하는 서버로 설정해야 합니다./.well-known가 웹 서버 설정에 의해 특별히 처리되면 /.well-known/acme-challenge의 파일이 웹 서버에서 서비스를 제공하는지 확인하기 위해 설정을 수정해야 할 수도 있습니다.

    4. Express API 서버에 서명 인증서 설치


    API 서버의 구성 파일에 새 인증서를 설치해야 합니다.
    먼저 다음과 같은 모듈을 설치하고 가져와야 합니다.
    yarn add https
    
    // import packages
    const https = require('https');
    const fs = require('fs');
    
    // serve the API with signed certificate on 443 (SSL/HTTPS) port
    const httpsServer = https.createServer({
      key: fs.readFileSync('/etc/letsencrypt/live/my_api_url/privkey.pem'),
      cert: fs.readFileSync('/etc/letsencrypt/live/my_api_url/fullchain.pem'),
    }, app);
    
    httpsServer.listen(443, () => {
        console.log('HTTPS Server running on port 443');
    });
    
    또한 HTTP 개의 요청 중 HTTPS 개의 요청을 유지하려면 다음 줄을 추가할 수 있습니다.
    const http = require('http');
    
    // serve the API on 80 (HTTP) port
    const httpServer = http.createServer(app);
    
    httpServer.listen(80, () => {
        console.log('HTTP Server running on port 80');
    });
    
    최종 API 서버 코드는 다음과 같습니다.
    // import required packages
    const express = require('express');
    const cors = require('cors');
    
    const https = require('https');
    const http = require('http');
    
    const fs = require('fs');
    
    
    const app = express();
    app.use(cors());
    
    // create new express app and save it as "app"
    const app = express();
    app.use(cors());
    
    // create a route for the app
    app.get('/', (req, res) => {
      res.send('Hello dev.to!');
    });
    
    // another route
    app.get('/omergulen', (req, res) => {
      res.send('Hello Omer! Welcome to dev.to!');
    });
    
    // Listen both http & https ports
    const httpServer = http.createServer(app);
    const httpsServer = https.createServer({
      key: fs.readFileSync('/etc/letsencrypt/live/my_api_url/privkey.pem'),
      cert: fs.readFileSync('/etc/letsencrypt/live/my_api_url/fullchain.pem'),
    }, app);
    
    httpServer.listen(80, () => {
        console.log('HTTP Server running on port 80');
    });
    
    httpsServer.listen(443, () => {
        console.log('HTTPS Server running on port 443');
    });
    

    5. 인증서의 자동 업데이트 및 테스트


    시스템의 Certbot 패키지에는 인증서가 만료되기 전에 인증서를 자동으로 갱신할 수 있는cron 작업이나 시스템 타이머가 포함되어 있습니다.구성을 변경하지 않으면 Certbot을 다시 실행할 필요가 없습니다.다음 명령을 실행하여 인증서의 자동 갱신을 테스트할 수 있습니다.
    sudo certbot renew --dry-run
    
    certbot 갱신 명령은 다음 위치 중 하나에 설치됩니다.
    /etc/crontab/
    /etc/cron.*/*
    systemctl list-timers
    
    Certbot을 실행하기 위해 웹 서버를 정지하려면 내장 명령을 편집해서 --pre-hook 로고와 --post-hook 로고를 추가해서 웹 서버를 자동으로 정지하고 시작해야 합니다.예를 들어, 웹 서버가 HAProxy인 경우 다음을 certbot renew 명령에 추가합니다.
    --pre-hook "service haproxy stop" --post-hook "service haproxy start"
    
    자세한 내용은 Certbot documentation on renewing certificates를 참조하십시오.
    Certbot의 유효성 확인
    사이트 설정이 올바른지 확인하려면 브라우저의 https://yourwebsite.com/에 액세스하고 URL 표시줄에서 잠금 아이콘을 찾습니다.최첨단 장비가 설치되어 있는지 확인하려면 https://www.ssllabs.com/ssltest/로 이동하십시오.
    잘했어!당신은 이미 이 긴 강좌를 완성했습니다.
    이 절차를 적용하면 API 서버 URL로 이동할 수 있습니다Hello dev.to!.

    읽어주셔서 감사합니다.


    나는 이 강좌가 충분히 유용하기를 바란다.
    너는 여기서 나의 마지막 문장을 볼 수 있다.


    전화[email protected]로 연락 주셔서 감사합니다.
    나는 미래 문장의 건의와 요구를 받아들이고 싶다,cya😃
    새해 복 많이 받으세요!🥳🥳🥳

    좋은 웹페이지 즐겨찾기