티스토리 뷰

📚 스터디 인증!

[7/19] 1차 스터디 4일차

2022. 7. 19. 21:01

🌱  [인프런] 따라하며 배우는 노드, 리액트 시리즈 - 기본강의 

 

 

[무료] 따라하며 배우는 노드, 리액트 시리즈 - 기본 강의 - 인프런 | 강의

이 강의를 통해서 리액트와 노드를 어떻게 사용하는지 기본적인 내용들을 배울 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com

 

 

 # boiler-plate 만들기 (#11 ~ #12)

 

 

13+. 비밀번호 암호화 관련 User.js 추가사항

 

비밀번호가 아니라 다른 정보를 바꿀 때는 그냥 next(); 해줘야함.

User.js에서 비밀번호 수정할때 if(user.isModified('password'){...} 하고 else{next();} 까지 해줘야 user.save()로 넘어갈 수 있음. else{next();} 부분을 작성하지 않으면 계속 여기 머물러있음.

// User.js

userSchema.pre('save', function(next) {
  var user = this;

  if(user.isModified('password')) {
    bcrypt.genSalt(saltRounds, function(err, salt) {
      if(err) return next(err)
  
      bcrypt.hash(user.password, salt, function(err, hash){
        if(err) return next(err)
        user.password = hash
        next()
      })
    });
  }  else {	// else 부분 추가
    next();
  }
})

 

 

 

14. 로그인 기능 만들기

 

로그인 route 생성

// index.js

app.post('/login', (req, res) => {

  // 1. 요청된 이메일이 데이터베이스에 있는지 찾기
  // 2. 이메일이 데이터베이스에 있다면 비밀번호가 맞는지 확인
  // 3. 비밀번호까지 일치한다면 토큰 생성

});

 

 

1) findOne 메서드(몽고db메서드)로 데이터베이스에 입력받은 이메일이 있는지 확인해서 없으면

res.json데이터로 loginSuccess를 false로, message와 함께 return

// index.js

app.post('/login', (req, res) => {
  // 1. 요청된 이메일이 데이터베이스에 있는지 찾기
  User.findOne({ email: req.body.email }, (err, user) => {
    if(!user) {
      return res.json({
        loginSuccess: false,
        message: '입력한 이메일과 일치하는 유저가 없습니다.'
      });
    }
    
    // 2. 요청된 이메일이 데이터베이스에 있다면 비밀번호가 맞는지 확인

  });
  
  // 3. 비밀번호도 일치한다면 토큰 생성
  
});

 

2) 이메일이 일치하는 유저가 있다면 비밀번호가 맞는지 확인

User모델에 comparePassword라는 메서드를 만들어서 비밀번호 일치여부 확인에 사용

// index.js

app.post('/login', (req, res) => {
  // 1. 요청된 이메일이 데이터베이스에 있는지 찾기
  User.findOne({ email: req.body.email }, (err, user) => {
    if(!user) {
      return res.json({
        loginSuccess: false,
        message: '입력한 이메일과 일치하는 유저가 없습니다.'
      });
    }

    // 2. 요청된 이메일이 데이터베이스에 있다면 비밀번호가 맞는지 확인
    user.comparePassword(req.body.password, (err, isMatch) => {
      if(!isMatch) {
        return res.json({
          loginSuccess: false,
          message: '비밀번호가 일치하지 않습니다.'
        })
      }

      // 3. 비밀번호도 일치한다면 토큰 생성
    

    });
  });
});

 

입력받은 plainPassword와 db에 저장되있는 암호화된 비밀번호가 일치하는지 확인하려면

plainPassword를 암호화하여 서로 일치하는지 확인해야함 -> bcrypt.compare()

// User.js

userSchema.methods.comparePassword = function(plainPassword, cb) {
  bcrypt.compare(plainPassword, this.password, function(err, isMatch) {
    
    if(err) return cb(err); // 일치하지않으면 err
    cb(null, isMatch);  // 일치하면 err는 없고 isMatch(=true) 전달
    
  });
}

 

3) 비밀번호까지 일치하면 토큰을 생성해야함 -> 토큰생성을 위해 JSONWEBTOKEN이라는 라이브러리 설치

npm install jsonwebtoken --save

 

jsonwebtoken 참고: https://www.npmjs.com/package/jsonwebtoken

// User.js

const jwt = require('jsonwebtoken');
.
.
.
userSchema.methods.generateToken = function(cb) {
  var user = this;  // es5 문법

  var token = jwt.sign(user._id.toHexString(), 'secretToken');
  user.token = token;
  user.save(function(err, user) {
    if(err) return cb(err);
    cb(null, user); // save가 잘 됬으면 err는 없고 user(유저정보) 전달
  });
}

user._id에서 _id는 몽고db에서 생성된 _id부분.

user._id + 'secretToken' 해서 token 생성 -> token 해석할 때 'secretToken'를 넣으면 user._id가 나옴.

user._id.toHexString()은 user._id를 plain Object로 만들기위해 -> 안해주면 오류남

 

4) 토큰을 쿠키에 저장 (로컬스토리 등등 다른데도 가능. 여기서는 쿠키에 저장하는 방법으로 진행)

cookie-paresr 설치  :  npm install cookie-parser --save

// index.js

const cookieParser = require('cookie-parser')
app.use(cookieParser());
.
.
.
app.post('/login', (req, res) => {
  // 1. 요청된 이메일이 데이터베이스에 있는지 찾기
  User.findOne({ email: req.body.email }, (err, user) => {
    if(!user) {
      return res.json({
        loginSuccess: false,
        message: '입력한 이메일과 일치하는 유저가 없습니다.'
      });
    }

    // 2. 요청된 이메일이 데이터베이스에 있다면 비밀번호가 맞는지 확인
    user.comparePassword(req.body.password, (err, isMatch) => {
      if(!isMatch) {
        return res.json({
          loginSuccess: false,
          message: '비밀번호가 일치하지 않습니다.'
        })
      }

      // 3. 비밀번호도 일치한다면 토큰 생성
      user.generateToken((err, user) => {
        if(err) return res.status(400).send(err);

        // 토큰을 쿠키에 저장
        res.cookie('x_auth', user.token)
          .status(200)
          .json({
            loginSuccess: true,
            userId: user._id
          });
      });
      
    });
  });
});

 

5) POSTMAN으로 확인해보기

post방식으로 http://localhost:5000/login에 email과 password보냈을때 정상적으로 작동하는지 확인

 

반응형

'📚 스터디 인증!' 카테고리의 다른 글

[7/23] 1차 스터디 6일차  (0) 2022.07.26
[7/21] 1차 스터디 5일차  (0) 2022.07.21
[7/16] 1차 스터디 3일차  (0) 2022.07.16
[7/14] 1차 스터디 2일차  (0) 2022.07.14
[7/12] 1차 스터디 1일차  (0) 2022.07.12
프로필사진
개발자 삐롱히

프론트엔드 개발자 삐롱히의 개발 & 공부 기록 블로그