Archive

2021-04-28 TIL

|

2021-04-28 TIL


  • 오늘 한 것
    1. 학원 대면수업 (15:30~22:00) 프로젝트 기간
    1. 어드민 이벤트관리 게시글 업데이트 - 이벤트 게시판 관리 페이지에서 게시글 리스트를 클릭시 그에 대한 상세 데이터가 모달창으로 출력되고 이 곳에서 업데이트 및 삭제가 가능해야한다. 백엔드와 연동하여 어찌어찌 업데이트는 되게 만들었으나 이미지가 정상적으로 들어가지 않는걸 보아하니 쿼리문의 문제 혹은 서비스 클래스 부분에서 문제가 발생한 모양이다. 조장님과 같이 작업을 할 때는 정말 편했었는데 이 부분을 잘 모르는 팀원과 같이하니 고생이 이만저만 아니다.. 그래도 천천히라도 작업을 해주니까 마음은 놓이는데 기간에 맞춰서 완성을 잘 해주면 좋겠다.
    2. 전체 페이지 페이징 처리 로직 변경 - 기존에 날로만든 페이징 처리 로직은 이전, 다음 버튼 없이 페이징 숫자들을 그려서 넣는 방식이었는데 페이징을 그룹핑하지 않아서 페이징된 숫자들이 나오는대로 화면에 찍혀서 문제가 있었다. 이 부분을 기존의 코드를 살려서 살을 붙이려다가 실패하여 pagination.js 플러그인을 사용하기로 결정했다. 결국 로직을 전체적으로 갈아엎어야했고 지금까지 만든 모든 페이지의 페이징 처리 방식을 변경하는 대공사를 진행했다.

  • 내일 할 것
    1. 학원 대면수업(15:30~22:00) 프로젝트 기간
    2. 어드민 백엔드 연동
    3. boiler plate with react, node.js 수강



  • 끝으로

5월 5일 완성을 목표로 정진!

오늘의 한 줄 총평 : 팀 프로젝트에서 협업의 중요성을 깨닫는 중


Auth Boiler Plate with Node.js-Bcrypt 암호화

|

Boiler Plate with Node.js - Bcrypt 암호화


Bcrypt 비밀번호 암호화

bcrypt는 비밀번호 등 노출의 위험이 있는 데이터들을 암호화하는데 필요한 패키지이다

npm i --save bcrypt 설치

DB에 데이터 저장을 위해 save 메소드가 실행되기 전, pre 메소드를 통해 무언가 작업을 할 수 있다

bcrypt 공식문서를 참고하여 코드를 작성한다

여기서 salt라는 중요한 개념이 나온다

비밀번호를 해시 값으로 변환한다하더라도 단순한 단방향 변환은 의미가 없다

salt를 중간에 끼워주어서 비밀번호의 복호화를 더욱 어렵게 하는것이다

// User.js

const bcrypt = require('bcrypt');
const saltRounds = 10;

userSchema.pre('save', function(next){ // save 전 실행
  var user = this; // 현재 스키마에 값이 저장되므로 this로 받음
  // 비밀번호 암호화
  if (user.isModified('password')) { // 분기점
    bcrypt.genSalt(saltRounds, function(err, salt){ // salt 생성, saltRounds 넣고 콜백
      if (err) return next(err);

      bcrypt.hash(user.password, salt, function(err, hash){ // 비번,솔트 넣고 콜백 실행
        if (err) return next(err);
        user.password = hash; // 변환된 hash값을 대입
        next(); // next로 다시 save 단계로 넘어감
      });
    });
  }
});

주의 : this 바인딩 문제로 pre 내에서는 arrow function 사용하면 안된다


성공

postman을 이용해 테스트를 해보면 비밀번호가 정상적으로 암호화된 것을 볼 수 있다!


Login with bcrypt

본격 로그인 기능 만들기

index.js에 post로 클라이언트가 요청한 작업을 수행할 내용을 작성한다

app.post('/login', (req, res) => {
  // 클라가 요청한 이메일을 DB에서 검색
  User.findOne({ email: req.body.email }, (err, user) => {
    if (!user) { // 해당 유저가 없으면
      return res.json({
        loginSuccess: false,
        message: '아이디가 일치하지 않습니다',
      });
    } else {
      // 이메일이 DB에 있으면 비밀번호 대조
      user.comparePassword(req.body.password, (err, isMatch) => {
        if (!isMatch) { // 요청 비번이 일치하지 않으면
          return res.json({
            loginSuccess: false,
            message: '비밀번호가 일치하지 않습니다',
          });
        } else {
          // 비밀번호 맞으면 Token 생성
          user.genToken((err, user) => {}); // 다음 강의 계속
        }
      });
    }
  });
});

위의 comparePassword는 custom method이다

User.js에서 스키마를 이용하여 작성한다

// User.js

userSchema.methods.comparePassword = function (plainPassword, cb) {
  // 요청받은 비밀번호를 암호화 후 DB의 비번과 대조
  bcrypt.compare(plainPassword, this.passowrd, function (err, isMatch) {
    if (err) return cb(err); // isMatch 적지않은 이유는 false기 때문
    cb(null, isMatch);
  });
};

마찬가지로 this 바인딩 문제로 arrow function은 사용하지 않았다

토큰 생성은 다음에 계속~



참고 자료


기초 노드 리액트 강의 - John Ahn

Auth Boiler Plate with Node.js-Nodemon, 설정정보 관리

|

Boiler Plate with Node.js - Nodemon, 설정정보 관리


Nodemon

코드 수정시 자동으로 서버를 재시작하는 유용한 패키지이다

npm i --save-dev nodemon development 환경에서만 필요한 패키지이므로 dev로 패키지를 설치했다

package.json의 scripts에 명령어를 추가한다

기존 start 명령어를 node index.js로 연결했는데 이제 nodemon index.js를 이용하여 실행하면 된다

명령어 이름은 아무거나 편한데로~

nodemon


비밀 설정정보 관리

몽고DB의 connect용 application code에 내 아이디, 비밀번호 같은 노출하면 안되는 정보가 적혀있다

이런 파일들은 모두가 이용하는 깃헙 등에 포스팅하게 되면 악용의 위험이 있다

config라는 폴더를 만들어 dev.js에 다음과 같이 적었다

module.exports = {
  mongoURI:
    'mongodb+srv://<id>:<pwd>@ytubecloneproject.rzk32.mongodb.net/myFirstDatabase?retryWrites=true&w=majority',
};

저 모듈은 ignore에 추가해서 업로드를 막는다

개발모드에서는 저 모듈을 가져와서 사용하면 되지만 배포 후에는 외부 서비스를 이용한다

heroku.com 헤로쿠에 접속하여 회원가입 후 settings에 key, value로 위 모듈에서 적었던 것을 입력한다

배포 후에는 이 헤로쿠의 서비스를 이용하여 application code를 삽입한다

개발환경과 배포환경의 분기점을 나눌 파일을 생성한다

config 폴더에 key.js와 prod.js를 추가적으로 생성

// key.js

if (process.env.NODE_ENV === 'production') { // 분기점을 나눈다
  module.exports = require('./prod');
} else {
  module.exports = require('./dev');
}
// prod.js

module.exports = {
  mongoURI: process.env.MONGO_URI, // MONGO_URI는 Heroku에 등록한 key값과 동일하게 작성
};
// index.js

const config = require('./config/key');

mongoose
  .connect(config.mongoURI, { // 기존 코드 제거 후 key.js를 사용
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true,
    useFindAndModify: false,
  })
  .then(() => console.log('MongoDB Connected..'))
  .catch((err) => console.log(err));

접속 테스트 성공을 확인한다



참고 자료


기초 노드 리액트 강의 - John Ahn

2021-04-27 TIL

|

2021-04-27 TIL


  • 오늘 한 것
    1. 학원 대면수업 (15:30~22:00) 프로젝트 기간

    2. 어드민 페이지 작업 - 어드민 운영자 관리 페이지에서 운영자 등록을 하는데 비밀번호를 어떻게 설정하는지가 이슈였다. 그래서 등록시 초기 비밀번호를 주고 비밀번호 변경 페이지를 만들어서 운영자가 비밀번호를 변경할 수 있도록 했다. 또, 어드민 페이지도 로그아웃을 할 수 있도록 버튼을 만들었다.

      백엔드와 작업을 하면서 추가적으로 필요한 부분을 만들거나 빼는 작업을 진행하고 있다. 어드민 페이지를 마크업하면서 임시로 만들었던 부분이 많아서 이 부분은 계속해서 백엔드 팀원들과 얘기를 하면서 추가적인 수정이 필요할 듯 싶다.

    3. Auth boiler plate clone - bcrypt 패키지를 이용해서 비밀번호를 암호화하는 방법을 배웠다. 비밀번호를 DB에 저장하기 전에 몽구스의 pre 메소드를 이용해서 salt를 끼워넣은 복호화하기 어려운 암호를 만들어냈다. 뿐만 아니라 nodemon, body-parser 등 정말 좋은 패키지들을 많이 알았다.


  • 내일 할 것
    1. 학원 대면수업(15:30~22:00) 프로젝트 기간
    2. 어드민 백엔드 연동
    3. boiler plate with react, node.js 수강



  • 끝으로

아무래도 프로젝트의 페이징 처리를 한 번 갈아엎어야 할 때가 온듯하다.

오늘의 한 줄 총평 : 내일은 무척이나 바쁠 예정


Auth Boiler Plate with Node.js-body-parser

|

Boiler Plate with Node.js - body-parser


Body-parser

npm i --save body-parser Body parser 패키지 설치

body-parser는 node.js 모듈로 클라이언트 POST request data의 body로부터

파라미터를 편리하게 추출할 수 있다

const bodyParser = require('body-parser');

// application/x-www-form-urlencoded 데이터 가져옴
app.use(bodyParser.urlencoded({extended: true}));
// application/json 데이터 가져옴
app.use(bodyParser.json());

body-parser에 옵션을 넣어준다


app.post('/register', (req, res) => {
  // 회원가입에 필요한 정보를 클라에서 가져와서 DB에 넣음
  const user = new User(req.body); // body-parser가 클라에서 보낸 데이터를 body에 담음
  
  user.save((err, userInfo) => { // DB 저장 후 콜백 함수 실행
  	if (err) return res.json({ success: false, err });
   	return res.status(200).json({ success: true });
  });
});

save()는 몽고DB에서 제공하는 메소드로 DB에 데이터 저장 후 콜백 함수를 실행한다

클라에 보낼 response에 json 형식으로 성공 여부와 실패시의 에러 메시지를 담아서 보낸다

테스트를 위해 postman을 설치하여 데이터를 보내본다

http://localhost:5000/register로 JSON 형태의 데이터를 body에 담아서 POST로 보낸다

postman

테스트 성공~



참고 자료


기초 노드 리액트 강의 - John Ahn