일반적으로 개발 환경 즉, 로컬호스트 환경에서는 자동적으로 http가 적용된다.
필자의 경우, 백엔드 파트로부터 api 명세를 넘겨 받아서 개발을 하는 과정에서 문제가 생겼다. 서버쪽에서는 이미 https로 암호화된 도메인을 사용하는데 클라이언트 사이드에서는 http를 사용했기 때문이었다.
그렇다면 개발환경을 배포환경과 일치시켜 개발을 편리하게 해보자.
// windows
choco install mkcert
// macOS
brew install mkcert
windows는 chocolatey가 설치되어 있어야하고, macOS의 경우 brew가 설치되어 있어야한다.
choco 또는 brew 명령어를 이용해서 mkcert를 설치해보자.
mkcert is a simple tool for making locally-trusted development certificates. It requires no configuration.
"mkcert는 로컬에서 신뢰할 수 있는 개발 인증서를 만들기 위한 간단한 도구입니다. 복잡한 설정을 할 필요가 없습니다." 라고 공식 깃허브에 설명이되어 있다.
로컬 인증 기관을 로컬 환경에 설치한다.
mkcert -install
이 방식은 설치한 컴퓨터에서만 가능하다. 다른 컴퓨터에서 프로젝트를 clone해서 작업을 하려는 경우 mkcert 환경을 다시 한번 세팅해줘야 한다.
프로젝트 루트 경로에서 다음 키워드를 입력해보자.
mkcert localhost
위 커맨드는 localhost에 대한 key, cert를 현재 경로에 생성한다는 의미이다.
localhost-key.pem, localhost.pem 파일이 생성된 것을 확인할 수 있다.
기존에는 next의 dev 스크립트로 개발 환경을 사용했지만 https를 적용하려면 내부적으로 서버를 커스텀해서 사용해야 한다.
루트 경로에 server.js를 생성한다.
const { createServer } = require('https');
const { parse } = require('url');
const next = require('next');
const fs = require('fs');
const hostname = 'localhost';
const port = 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();
const httpsOptions = {
key: fs.readFileSync('./localhost-key.pem'),
cert: fs.readFileSync('./localhost.pem'),
};
app.prepare().then(() => {
createServer(httpsOptions, async (req, res) => {
try {
const parsedUrl = parse(req.url, true);
await handle(req, res, parsedUrl);
} catch (err) {
console.error('Error occurred handling', req.url, err);
res.statusCode = 500;
res.end('internal server error');
}
}).listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on https://${hostname}:${port}`);
});
});
package.json으로 이동해서 scripts 부분을 설정해보자.
나는 명령어를 secure로 설정했다. 명령어는 마음애 드는대로 설정하자.
{
"scripts": {
"secure": "node server.js",
},
}
새로운 인원이 참여할때마다 위 과정을 거쳐 세팅을 하게 되면 시간도 오래걸리고 생산성에 영향을 미칠수 밖에 없다.
위 과정을 쉘스크립트를 이용해서 자동화해보자.
루트 경로에 init-https.sh파일을 생성한다.
#!/bin/bash
MKCERT_INSTALLED=$(which mkcert)
# install mkcert
if [ -z $MKCERT_INSTALLED ];then
brew install mkcert
fi
# Create server.js file
cat <<EOT >> server.js
const { createServer } = require('https');
const { parse } = require('url');
const next = require('next');
const fs = require('fs');
const hostname = 'localhost';
const port = 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();
const httpsOptions = {
key: fs.readFileSync('./localhost-key.pem'),
cert: fs.readFileSync('./localhost.pem'),
};
app.prepare().then(() => {
createServer(httpsOptions, async (req, res) => {
try {
const parsedUrl = parse(req.url, true);
await handle(req, res, parsedUrl);
} catch (err) {
console.error('Error occurred handling', req.url, err);
res.statusCode = 500;
res.end('internal server error');
}
}).listen(port, (err) => {
if (err) throw err;
console.log(\`> Ready on https://\${hostname}:\${port}\`);
});
});
EOT
mkcert -install
mkcert localhost
위 코드를 추가하자.
macOS 기준으로 작성된 쉘 스크립트이다.
mkcert설치 여부를 확인하고 설치가 안되어있다면 brew로mkcert를 설치한다.- 현재 경로에
server.js파일을 생성하고 코드를 추가해준다.- mkcert -install 실행
- mkcert localhost 실행
package.json 스크립트에 코드를 추가한다.
{
"scripts": {
"secure": "node server.js",
"init-https": "sh init-https.sh"
},
}
마지막으로 localhost-key.pem, localhost.pem은 .gitigonore에 등록해준다.