[Node.js/React] 로그인 기능 생성

·2023년 6월 29일
0

node-react 기초 공부

목록 보기
8/12
post-thumbnail

회원가입 부분은 틀은 대략 잡혔으므로, 로그인 api를 생성해볼것이다.
UserSchema의 값 중 email값을 통해 유저를 조회하고, 해당 password가 맞을 경우, 로그인에 성공하도록 할 것이다. 즉, emailpassword값이 로그인을 할 때 필수값이 된다.

우선 여기 포스팅된 코드는 오류가 발생하는 코드이다 - 해당 오류를 해결한 과정은 다음 포스팅에 작성할 예정이다.


✏️ 이메일 조회

login에서는 3가지의 과정을 거친다.

  1. 사용자가 입력한 이메일의 계정이 DB에 존재하는가
  2. 해당 이메일 계정의 비밀번호가 일치하는가
  3. 비밀번호가 일치한다면 token 생성

우선은 1번, 2번까지만 해결해보자.

이메일 조회하는 코드는 아래와 같다.
mongoDB에서 제공되는 findOne함수를 통해 사용자가 입력한 email값을 조회한다. 만약 해당 값이 존재하지 않다면 loginSuccessfalse값을, message는 해당 유저가 없다는 메시지를 json형식으로 전달한다.

// index.js

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

    // 요청된 이메일이 DB에 있는지 조회
    User.findOne({ email: req.body.email }, (err, user) => {
        if (!user) {
            return res.json({
                loginSuccess: false,
                message: "제공된 이메일에 해당하는 유저가 없습니다."
            })
        }
        // 해당 이메일이 있다면 비밀번호가 맞는지 확인
            // 비밀번호 확인되면 토큰 생성
    })
})

✏️ 비밀번호 compare

비밀번호는 그 전의 포스팅을 보면 알겠지만, DB에 비밀번호의 값이 그대로 보이지 않도록 설정했기 때문에, 해시 값과 사용자가 입력한 비밀번호가 일치하는지 확인하는 과정의 코드가 필요하다.

comparePassword함수를 생성하여 plainPWthis.password를 비교한다.

  • plainPW: 사용자가 회원가입할 때 입력했던 값
  • this.password: 입력한 비밀번호(+salt)의 해시값

이 두 값을 bcrypt.compare을 통해 비교하여 일치하지 않으면 err값을 반환하고, 일치하면 isMatch값이 true임을 반환한다.

// User.js
userSchema.methods.comparePassword = function (plainPW, cb) {

    bcrypt.compare(plainPW, this.password, function (err, isMatch) {
        if (err) return cb(err)
      	cb(null, isMatch) //isMatch == true
    })
}

index.js에선 반환된 isMatch값이 true가 아니라면 loginSuccess값은 false, message에는 비밀번호가 틀렸다는 메시지를 반환한다.
isMatchtrue라면 해당 비밀번호에 대한 token을 생성한다.

// index.js

// 해당 이메일이 있다면 비밀번호가 맞는지 확인
user.comparePassword(req.body.password, (err, isMatch) => {
	if (!isMatch)
		return res.json({ loginSuccess: false, message: "비밀번호가 틀렸습니다." })


✏️ 추가된 코드

index.js

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

    // 요청된 이메일이 DB에 있는지 조회
    User.findOne({ email: req.body.email }, (err, user) => {
        if (!user) {
            return res.json({
                loginSuccess: false,
                message: "제공된 이메일에 해당하는 유저가 없습니다."
            })
        }
        // 해당 이메일이 있다면 비밀번호가 맞는지 확인
        user.comparePassword(req.body.password, (err, isMatch) => {
            if (!isMatch)
                return res.json({ loginSuccess: false, message: "비밀번호가 틀렸습니다." })

            // 비밀번호 확인되면 토큰 생성
        })
    })
})

User.js

userSchema.methods.comparePassword = function (plainPW, cb) {

    bcrypt.compare(plainPW, this.password, function (err, isMatch) {
        if (err) return cb(err), cb(null, isMatch)
    })
}

✏️오류 발생 - MongooseError Callback 관련

자.. 이제 내가 하면서 약간 스트레스 받았던 오류가 발생한다😩🥹
위와 같이 코드를 입력하고 서버를 키면 아래와 같은 오류가 발생한다

오류 발생 이유
Mongoose 6 버전 이전에는 Model.prototype.save()에 콜백 함수를 전달하여 비동기 작업이 완료될 때 실행되도록 할 수 있었지만, Mongoose 6에서는 이러한 방식의 사용이 중단되었다.

// Error
MongooseError: Model.prototype.save() no longer accepts a callback at model.save

이 error는 async/await 또는 Promise를 사용하여 비동기 작업을 처리해야 한다.
근데 다음 작업이 jwt를 이용하여 비밀번호를 저장하는 것이기 때문에 그를 하면서, 고칠 예정이었기 때문에 다음 포스팅에 정리하도록 하겠다 !
(정리해서 올리게 되면 아래에 링크를 달아둘것이다)
오류 해결 포스팅


👩‍💻 깃허브 주소

node-react

0개의 댓글