해결된 질문
작성
·
322
·
수정됨
0
로그인 후 개발자 도구 쿠키에 x_auth 정상적으로 확인
DB에도 토큰 정상적으로 값 입력된 것 확인
로그아웃 버튼을 클릭 시 401 에러 발생, 토큰 삭제 x
server/index.js
app.post('/api/users/login', async (req, res) => {
try {
const user = await User.findOne({ email: req.body.email });
if (!user) {
return res.json({ loginSuccess: false, message: "제공된 이메일에 해당하는 유저가 없습니다." });
}
// 비밀번호가 일치하는지 확인한다.
const isMatch = await user.comparePassword(req.body.password);
if (!isMatch) {
return res.json({ loginSuccess: false, message: "비밀번호가 틀렸습니다." });
}
// 비밀번호가 일치하다면 토큰을 생성한다.
const tokenUser = await user.generateToken();
res.cookie("x_auth", tokenUser.token)
.status(200)
.json({ loginSuccess: true, userId: user._id });
} catch (err) {
return res.status(400).send(err);
}
});
app.post('/api/users/logout', auth, async(req, res) => {
try {
await User.findOneAndUpdate({ _id: req.user._id }, { token: "" });
res.clearCookie("x_auth");
return res.status(200).send({ logoutSuccess: true });
} catch (err) {
return res.json({ logoutSuccess: false, message: err.message });
}
});
User.js
userSchema.methods.comparePassword = function(plainPassword, cb) {
const user = this;
return bcrypt.compare(plainPassword, user.password);
};
userSchema.methods.generateToken = function() {
var user = this;
// jsonwebtoken을 이용해서 토큰을 생성한다.
var token = jwt.sign(user._id.toJSON(), 'secretToken');
user.token = token;
return user.save();
};
userSchema.statics.findByToken = async function(token) {
const user = this;
try {
// 토큰을 decode합니다.
const decoded = jwt.verify(token, 'secretToken');
// 디코딩된 정보를 이용해 유저를 찾습니다.
const userData = await user.findOne({
"_id": decoded,
"token": token
});
return userData;
} catch (err) {
throw new Error("유효하지 않은 토큰입니다.");
}
};
auth.js
const { User } = require("../models/User");
function auth(req, res, next) {
// 인증 처리한다.
// 클라이언트 쿠키에서 토큰을 가져온다.
const token = req.cookies.x_auth;
if (!token) {
return res.status(401).json({
isAuth: false,
message: "토큰이 제공되지 않았습니다."
});
}
// 토큰을 복호화한 후 유저를 찾는다.
User.findByToken(token)
.then((user) => {
if (!user) {
return res.status(401).json({
isAuth: false,
message: "유효하지 않은 토큰입니다."
});
}
// 토큰과 유저정보를 다음 단계로 전달한다.
req.token = token;
req.user = user;
next();
})
.catch((err) => {
return res.status(401).json({
isAuth: false,
message: err.message
});
})
};
module.exports = { auth };
서버의 경로를 절대 경로로 기입하지 않으면 404 에러 발생
5000 포트로 데이터 전송, cors로 3000 포트로 이동하도록 설정
const corsOptions = {
origin: 'http://localhost:3000', // 클라이언트 주소
credentials: true // 쿠키를 포함하도록
};
app.use(cors(corsOptions));
답변 2
0
2가지를 수정하였더니 해결이 되었습니다 !
로그인 시 쿠키 설정 확인
-
path, domain, secure, sameSite 등의 기본값이 적용되므로 확인 필요
app.post('/api/users/login', async (req, res) => {
// ... 생략
const tokenUser = await user.generateToken();
res.cookie("x_auth", tokenUser.token, { httpOnly: true, secure: false, sameSite: 'lax', path: '/' })
.status(200)
.json({ loginSuccess: true, userId: user._id });
} catch (err) {
return res.status(400).send(err);
}
});
로그아웃 시 쿠키 전송 확인
- withCredentials: true를 올바르게 사용
const onClickHandler = () => {
axios.post('http://localhost:5000/api/users/logout', {}, { withCredentials: true })
.then(response => {
//.. 생략
});
};
혹시나 로그아웃에 헤매고 계시다면 조금이나마 도움이 되었으면 합니다 😄
완강까지 모두 화이팅이에요 !
0
안녕하세요, 인프런 AI 인턴입니다.
마이히님께서 겪고 계신 로그아웃 시의 401 Unauthorized 에러 문제에 대해 몇 가지 확인해볼 수 있는 사항들이 있습니다.
로그아웃 요청을 보낼 때, 서버에서 인증 토큰을 처리하는 부분에서 문제가 발생하여 401 에러를 반환하는 상황입니다. 이는 주로 인증 관련 문제일 가능성이 높습니다.
토큰 유효성 확인
auth.js
에서 쿠키에서 토큰을 가져올 때, 잘못된 값을 반환하거나 쿠키 자체가 없어서 오류가 발생할 수 있습니다. 콘솔을 통해 req.cookies.x_auth
의 값을 확인하여 제대로 된 토큰이 있는지 확인해 보세요.CORS 설정
credentials: true
로 설정하였지만, Access-Control-Allow-Credentials
헤더가 제대로 전달되고 있는지 확인이 필요합니다. 이는 클라이언트와 서버 간의 쿠키 전달을 허용하도록 하는 매우 중요한 설정입니다.오타 및 미세한 오류 확인
auth
미들웨어에서 req.token = token;
및 req.user = user;
설정이 로그아웃 라우트까지 제대로 반영되고 있는지 확인해 보세요.서버 로그 확인
유사한 문제를 해결한 기존의 질문을 참고하시면 도움이 될 수 있습니다. 비슷한 문제와 해결 방법이 소개된 질문들을 소개합니다.
이들 링크를 통해 비슷한 문제를 겪은 다양한 사용자들의 해결 방법을 확인하실 수 있으니, 해당 내용을 참고하시어 문제를 해결하실 수 있기를 바랍니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.