본문 바로가기
오늘의뻘짓

[따라하며 배우는 노드js] 13강 오류

by 강갱민 2023. 11. 24.



오류의 원인
Mongoose 업데이트 후 발생하는 `findOne()` 메서드 오류
최근 Mongoose 버전에서는 `Model.findOne()` 메서드가 더 이상 콜백 방식을 지원하지 않습니다. 이는 Mongoose가 비동기 작업을 처리하기 위해 프로미스(Promises)와 async/await 패턴을 더 적극적으로 사용하고 있음을 반영합니다. 이로 인해 기존에 콜백을 사용하던 코드는 오류를 발생시키게 됩니다.

발생한 오류


MongooseError: Model.findOne() no longer accepts a callback


해결 방법

1. `findByToken` 메서드 업데이트:

   `findByToken` 메서드를 프로미스 기반으로 변경합니다. `jwt.verify`는 여전히 콜백을 사용하지만, `findOne`은 프로미스를 반환하도록 수정합니다.

  javascript


userSchema.statics.findByToken = function (token) {
    const user = this;

    return new Promise((resolve, reject) => {
        jwt.verify(token, 'secretToken', function (err, decoded) {
            if (err) {
                reject(err);
            } else {
                user.findOne({ '_id': decoded, 'token': token })
                    .then(user => resolve(user))
                    .catch(err => reject(err));
            }
        });
    });
};




2. `auth` 미들웨어에서의 사용:
   `auth` 미들웨어에서 `findByToken`을 프로미스 기반으로 사용합니다.

   javascript

let auth = (req,res,next) =>{
// 인증처리를 하는곳

// 클라이언트 쿠키에서 토큰 가져온다.
let token =req.cookies.x_auth;


// 토큰을 복호화 한 후 유저를 찾는다.
User.findByToken(token)
.then(user => {
    if (!user) return res.json({ isAuth: false, error: true });

    req.token = token;
    req.user = user;
    next();
})
.catch(err => {
    return res.status(400).send(err);
});
//유저가 있으면 인증 okay


}



3. `logout` 라우트에서의 `findOneAndUpdate` 변경:

   `logout` 라우트에서도 `findOneAndUpdate` 메서드를 프로미스를 사용하도록 변경합니다.

   javascript

// auth 미들웨어를 사용하는 이유는 req.user 데이터를 사용하기 위함
app.get('/api/users/logout', auth, (req, res) => {
  User.findOneAndUpdate({ _id: req.user._id }, { token: "" })
      .then(user => {
          if (!user) return res.json({ success: false, error: "User not found" });
          return res.status(200).send({ success: true });
      })
      .catch(err => {
          return res.json({ success: false, err });
      });
});



 결론

이러한 변경을 통해, Mongoose의 최신 버전에서 발생하는 `Model.findOne() no longer accepts a callback` 오류를 해결할 수 있습니다. 프로미스를 사용하면 코드가 더욱 깔끔해지고, 비동기 작업을 더 효율적으로 관리할 수 있습니다.