TIL 38일차 - node 심화주차 복습, .env 환경변수 추가 설정

박찬웅·2023년 3월 15일
0

항해99

목록 보기
43/105

23년 3월 15일

배운 것

오늘은 딱히 배운것 보다는 지금까지 주특기에서 공부했던 것을 간단하게 복습을 하였고, 어제 LV4를 구현 하고 나서 내가 이용하고 있는 RDS와 JWT 생성 비밀키를 안보이게 설정하는 방법을 구현하였다.

시도 한 것

일단 오늘은 시도 한 것이라면 한게 거의 없었다. 원래라면 lv5 개인과제를 해야 했지만, 내일 갑작스럽게 심화주차 시험이 생겼기 때문에, 이전에 주특기로 공부 했던 것을 복습하는 시간을 가졌다.
먼저 입문 주차때는 express 모듈을 사용하고, mongoose 패키지로 nosql 방법으로 api를 구현하는 연습을 하였다. 숙련 주차때는 역시 express를 사용했고 jwt를 이용해서 토큰을 생성해서 로그인 한사람만 게시글이나 댓글을 생성, 수정, 삭제를 할 수 이쎅 구현하였고, 또한 Sequelize 패키지로 mysql로 api를 구현하였다. 그리고 심화 주차때에는 개인과제에서는 구현하지는 않았던 부분이지만, 실무에서는 나름 자주 사용한다는 socket.io, 객체지향이랑 solid 방식, 그리고 계층 아키텍쳐 패턴들이 있었다. lv5 개인과제가 lv4 완성 했던 코드에서 3계층 아키텍처로 분리 해보는 작업이였는데, 결국 시도는 안했고, 강의 노트를 보면서 어떻게 코드가 굴러가는지 복습정도만 하였다. 그래서 오늘 딱히 새로운걸 배우는 것보다는 그냥 내일 시험을 위해서 용어들 정리정도만 한 것으로 끝났다.

그리고 어제 자기 직전에 다른 조 팀원들한테 들은 내용이였는데 comfig.json에 파일을 그대로 깃허브에 올려버리면 내가 지금 이용하고 있는 데이터베이스 주소는 물론 비밀번호까지 다 노출되어있는 보안의 문제가 있다는 것을 알게 되었다. 그래서 .env를 이용해서 그 부분을 안보이게 하는 방법을 알게되서 이 부분을 어젯밤에 구현하였다. 하는 방법은 다른 조 팀원들에게 도움을 받아서 설정을 하였다.

지금부터 설명하는 것은 개인과제 lv3~4때 구현했던 sequelize로 구현했을 때 기준이다.
먼저 .env를 숨길 수 있는 패키지인 dotenv를 설치하기 위해서 npm install dotenv를 터미널에 입력해 설치해 준다.

# Private key
PRIVATE_KEY = "token을 생성할때 사용하는 비밀키"

# config private key
MYSQL_USERNAME = "사용하고 있는 유저네임"
MYSQL_PASSWORD = "사용하고 있는 비밀번호"
MYSQL_DATABASE = "사용하고 있는 데이터베이스 이름"
MYSQL_HOST = "사용하고 있는 RDS 주소"

그런 다음에 .env 파일을 가장 최상위에다 만들어 주고 나서 다음과 같이 변수를 만들어 주면 된다. .gitignore에다 이미 node.js 관련된 모든 파일을 다 적었다면 아마 .env도 포함 되었기 때문에 git에다 커밋푸시 해도 .env 파일은 커밋되지 않는다. 지금은 한글로 예시를 적었는데 지금 본인이 사용하고 있는 데이터베이스 이름, 비밀번호, 데이터베이스명, 사용하고 있는 주소를 넣으면 된다.

const config = require(__dirname + '/../config/config.js')[env];

그런 다음에 models폴더에 index.js 파일로 가보면 const config 줄을 찾아서(아마 9번째 줄쯤에 있다) 원래 config.json이였을텐데 config.js로 바꿔준다.

require('dotenv').config();
const env = process.env;

  const development = {
    "username": env.MYSQL_USERNAME,
    "password": env.MYSQL_PASSWORD,
    "database": env.MYSQL_DATABASE,
    "host": env.MYSQL_HOST,
    "dialect": "mysql"
  };

  const test = {
    "username": env.MYSQL_USERNAME,
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  };

  const production = {
    "username": env.MYSQL_USERNAME,
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }

module.exports = {development, test, production};

그리고 기존에 있던 config 폴더 안에 있던 config.json파일을 config.js로 이름을 바꿔준 다음 다음과 같이 코드로 바꿔 주면 된다. 이러면 내가 사용하고 있던 데이터베이스는 완벽하게 가릴 수 있다.

const jwt = require("jsonwebtoken");
require('dotenv').config(); // 추가 된 코드
const { Users } = require("../models");

module.exports = async (req, res, next) => {
    try {
    const { Authorization } = req.cookies;
    const [tokenType, token] = (Authorization ?? "").split(" ");
    if (tokenType !== "Bearer" || !token) {
      return res.status(403).json({ errorMessage: "로그인 후 이용 가능합니다." });
    }
	  // 기존에 사용했던 비밀키를 process.env.PRIVATE_KEY로 바꿔준다.
      const { userId } = jwt.verify(token, process.env.PRIVATE_KEY); 

      const user = await Users.findOne({ where : {userId} }); // sequelize 사용할 때에는 where 절을 사용할 것
      res.locals.user = user;
      next();

    } catch (error) {
      return res.status(403).json({
        errorMessage: "전달된 쿠키에서 오류가 발생하였습니다."
      });
    }
}

하지만 jwt 토큰 생성할때 사용하고 있는 비밀키도 가려야 하기 때문에 먼저 미들웨어 폴더에 있는 auth-middleware.js파일에서도 위에 코드랑 같이 최상단에 require('dotenv').config(); 를 추가 하고 비밀키를 다음과 같이 변경해주면 된다.

const express = require("express");
require('dotenv').config(); // 추가 된 코드
const router = express.Router();
const { Users } = require("../models");
const jwt = require("jsonwebtoken");

...(로그인 API 구현하기 위한 코드 생략)

// 기존에 사용했던 비밀키를 process.env.PRIVATE_KEY로 바꿔준다.
const token = jwt.sign({ userId: user.userId }, process.env.PRIVATE_KEY);

마지막으로 routes 폴더에 자신이 로그인 API 구현한 파일로 가서 역시 동일하게 최상단에 require('dotenv').config();를 추가 하고 비밀키도 다음과 같이 변경하면 비밀키도 완벽하게 가릴 수 있다.

이러면 깃에 올려도 내가 쓰고 있는 데이터베이스랑 비밀키를 깃에다 올려도 안전하게 다른사람에게 노출되지 않고 관리가 가능하다.

해결

.env 설정을 통해서 내가 사용하고 있는 데이터베이스 정보랑 token에 사용하는 비밀키를 가려서 보안을 한층 강화하였다. 그리고 내일 시험에 대비해서 개념들을 복습하였다.

알게 된 점

오늘은 아까도 말했듯이 내일 시험을 대비해서 기존에 개념들을 다시 한번 보는것이 전부였다. 그래서 새로 배운건 딱히 없었었다. 하지만 여전히 트랜잭션이나 객체지향의 설계 5원칙인 SOLID, 그리고 3계층 아키택쳐 패턴은 여전히 이해하는데는 어려웠었다. 그리고 이거는 어제 했던 것이였지만 내가 사용했던 데이터베이스랑 비밀키를 안전하게 .env에다 안전하게 가릴 수 있는 방법을 옆조 팀원들에게 알게 되어서 보안을 한가지 추가 하는 방법을 알게 되었다. 이걸 알려준 옆조 분들에게도 감사하다고 전했고, 아쉬웠던 거는 항해에서 이런 민감한 부분을 가리는 걸 알려주지 않았기 때문에 살짝 이부분은 불만을 가지게 되었다. 그래도 이제라도 알았으니 앞으로는 이렇게 .env와 .gitignore를 이용해서 중요한 부분은 가리는 것을 알게 되었다.

앞으로 할 일

내일은 심화주차 시험이 있는 날인데, 어려운 시험은 아니고 지금까지 공부했던거 복습정도로 나온다고 했으므로, 부담없이 보고, 팀과제를 진행 할것 같다. 그리고 나서 시간이 남으면 지금까지 LV1~4 내가 구현했던 걸 코드를 리뷰 하는 시간을 가질 것 같다.

profile
향해 13기 node.js 백앤드

0개의 댓글