서론

로컬에서 개발할 때 http://localhost:8000 과 같은 형태의 URL을 상용하게 됩니다.
하지만 소셜 로그인을 local에서 수행하고 싶을 때
벤더사마다 다른 보안 정책으로 https 프로토콜에서만 로그인이 가능하도록 막아놓는 경우가 있습니다.
이런 경우 개발을 끝낸 뒤 배포 후 테스트 서버에서 확인해야 하는 번거로움이 생기게 됩니다.

본 포스팅에서 간략히 TLS(SSL) 개념에 대해 정리하고
localhost에서 https 적용 방법에 대해 설명드리겠습니다.

 

HTTP vs HTTPS

HttpHyper Text Transfer Protocol의 약자로 네트워크를 통해 데이터를 전송하기 위한 프로토콜입니다. 
Https의 S는 TLS 또는 SSL을 사용하여 HTTP 요청 및 응답 을 암호화하는 보안을 나타냅니다.

따라서 Http만 사용할 경우 네트워크에서 누군가 요청에 달린 데이터를 가로챌 수 있지만,
Https를 사용하면 암호화된 임의의 문자열만 보이게 됩니다.

cloudflare.com의 HTTP vs HTTPS

Https가 작동하려면 공개키 암호화(비대칭 암호 알고리즘)가 사용됩니다.
이 유형의 암호화는 두 개의 키를 사용합니다.
Public Key : 공개키는 서버의 SSL 인증서를 통해 클라이언트에게 공유됩니다.
Private Key :
개인키(비밀키)는 서버만 가지고 있는 키이고 클라이언트로 받은 암호화된 정보를 복호화할 때 사용됩니다.

geeksforgeeks.org 비대칭 암호화

따라서 localhost에서 https를 사용하려면 public key와 별도의 private key를 포함하는 인증서를 만들어야 합니다.
인증서가 유효하려면 사용 중인 사이트가 신뢰할 수 있음을 확인하는 인증 기관(CA)에서
도메인(localhost / 127.0.01)에 대해 발급받아야 합니다.

위 작업을 수행하기 위해 로컬에서 신뢰할 수 있는 인증서를 만들기 위해 mkcert를 설치합니다.

 

mkcert

mkcert를 전역적으로 설치합니다.

npm install -g mkcert

이제 CA(Certificate Authority)를 만들겠습니다.

mkcert create-ca

명령을 입력하면 실행한 곳에서 두가지 파일이 생성됩니다.
ca.key - CA private key
ca.crt - CA certificate

원래 Private Key는 안전한 위치에 저장하는 것이 중요하지만 설명하기 위해 위치를 변경하지 않겠습니다.

CA를 생성했으므로 다음 단계는 localhost 도메인의 인증서를 만들어야합니다.
아래와 같이 인증서를 만들 수 있습니다.

mkcert create-cert

원래 create-cert에 대한 다양한 옵션이 있습니다.
다만 도메인이 localhost일 경우 다른 옵션 없이 기본 값 옵션으로 명령을 수행해도 괜찮습니다.
이렇게해서 인증서(cert.crt)와 개인키(cert.key)가 생성되었습니다.

이제 필요한 파일이 있으므로 다음 단계는 cert.keycery.crt 파일을 프로젝트에 복사합니다.

 

Https 적용

const express = require("express");
const expressSanitizer = require("express-sanitizer");

// fs and https 모듈 가져오기
const https = require("https");
const fs = require("fs");

// certificate와 private key 가져오기
// ------------------- STEP 2
const options = {
  key: fs.readFileSync("./config/cert.key"),
  cert: fs.readFileSync("./config/cert.crt"),
};

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(expressSanitizer());
app.use("/", express.static("public"));

const PORT = 8000;

// http 서버는 8000번 포트로 실행
app.listen(PORT, () => {
  console.log(`Server started on port ${PORT}`);
});

// https 의존성으로 certificate와 private key로 새로운 서버를 시작
https.createServer(options, app).listen(8080, () => {
  console.log(`HTTPS server started on port 8080`);
});

서버 실행시 두개의 서버가 실행됩니다.
한개의 서버는 http 8000 포트로 실행된 서버,
다른 서버는 https 8080 포트로 실행된 서버입니다.

그럼 정상적으로 https로 localhost가 실행되는 것을 확인할 수 있습니다.