• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

id도 잘 불러오는데 토큰이 삭제가 안됩니다 .......

24.02.28 03:16 작성 조회수 72

0

index.js

app.get('/api/users/logout', auth, (req,res)=>{
    // Usermodel에서 id를 찾고 token을 지워줌
    User.findOneAndUpdate({ _id: req.user._id }, { token: "" }) 
    console.log(req.user._id)
    try{
        return res.status(200).send({ success: true })
    }
    catch(err){
        return res.json({ success: false, err });
    }
})
auth.js

let auth = (req, res, next)=> {

    // 인증 처리를 하는 곳

    // client 쿠키에서 토큰을 가져온다.
    let token= req.cookies.x_auth;

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

userSchema.statics.findByToken= function(token, cb){
    var user= this;

    //토큰 디코드
    jwt.verify(token,'secretToken', function(err, decoded){
        //유저 아이디를 이용하여 유저를 찾은 후
        // 클라이언트에서 가져온 token과 DB에 보관된 TOKEN이 일치하는지 확인
        user.findOne({"_id": decoded, "token": token})
        .then((user)=>{
            cb(null, user);
        })
        .catch((err)=>{
            return cb(err);
        })
    })
}

index.js / auth.js / User.js 첨부하겠습니다.
도저히 왜 토큰이 DB에서 사라지지 않는지 궁금합니다 ㅠㅠ

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.02.29

안녕하세요, 인프런 AI 인턴입니다.

권규리님의 코드에서 토큰이 DB에서 삭제되지 않는 문제를 살펴봤습니다.

index.js에서 User.findOneAndUpdate 메소드를 사용하셔서 토큰을 삭제하려고 하셨는데, 해당 메소드는 비동기 함수입니다. console.log로 id를 출력하는 것은 즉각적으로 실행되지만, 실제 데이터베이스의 토큰 삭제는 비동기적으로 수행됩니다.

이 코드 상에서는 비동기 동작의 결과를 기다리지 않고 바로 응답을 보내고 있으므로, 만약 데이터베이스 작업에 문제가 있어도 그 에러를 바로 캐치할 수 없습니다. 따라서 findOneAndUpdate 함수가 성공했을 때와 실패했을 때 각각 반응할 수 있도록 콜백 함수나 프로미스 체인, 혹은 async/await를 사용하여 처리하는 것이 좋습니다.

예를 들어, 다음과 같이 수정할 수 있습니다.

// async/await를 이용한 예
app.get('/api/users/logout', auth, async (req, res) => {
    // User model에서 id를 찾고 token을 지워줌
    try {
        await User.findOneAndUpdate({ _id: req.user._id }, { token: "" });
        return res.status(200).send({ success: true });
    } catch (err) {
        return res.status(400).send({ success: false, err });
    }
});

더불어 findOneAndUpdate 메소드 호출 후 이어지는 console.log는 try 블록 안에 넣어주시는 것이 좋습니다. 그렇게 해야 에러 발생 시 catch 블록으로 이동하여 에러를 처리할 수 있습니다.

위 내용을 통해 코드를 수정해보시고 테스트해보세요. 결과가 여전히 동일하다면, 데이터베이스 연결 상태등 추가적인 문제가 없는지 다시 확인해보세요.

응원합니다!