데이터베이스 제작 트러블 슈팅
배경
이번 프로젝트는 시작부터 우여곡절이 많았다. 여러 가지로 프로젝트가 작동이 안 되는 걸 수정하는 작업이 대부분을 차지했다.
진심으로 알파벳 하나 고칠 때마다 1시간씩 코드 봐가며 고쳐야 했던 것 같다.
실무에선 이거보다 어려운 일을 이런 식으로 풀어야 할 텐데 그 때 가면 분명 머리카락 다 빠질 게 분명하다.
이번 과정에서 거의 이틀을 잡아먹게 한 토큰 관련 정보를 확인하자.
발단
이번 프로젝트에선 클라이언트에서 토큰을 가지지 않는다고 해석을 해서 세션을 쓸 수 없다고 생각해 버렸다.
그래서 JWT 토큰을 작성하는 부분부터 다시 시작하여 프로젝트를 작성하게 되었다.
전개
인증 코드 자체는 기존에 배웠던 코드를 그대로 붙여 넣고 하나하나 붙여 넣는 식으로 작업하게 되었다.
export default async function (req, res, next) {
try {
const { authorization } = req.cookies;
if (!authorization) throw new Error('토큰이 존재하지 않습니다.');
const [tokenType, token] = authorization.split(' ');
if (tokenType !== 'Bearer')
throw new Error('토큰 타입이 일치하지 않습니다.');
const decodedToken = jwt.verify(token, process.env.JSONWEBTOKEN_KEY);
const userId = decodedToken.userId;
if(!userId) throw new Error('로그인이 필요합니다');
const user = await prisma.users.findFirst({
where: { UserId: userId },
});
if (!user) {
res.clearCookie('authorization');
throw new Error('토큰 사용자가 존재하지 않습니다.');
}
// req.user에 사용자 정보를 저장합니다.
req.userId = user.UserId;
next();
} catch (error) {
res.clearCookie('authorization');
//return res.status(400).json({message : error.message});
//토큰이 만료되었거나, 조작되었을 때, 에러 메시지를 다르게 출력합니다.
switch (error.name) {
case 'TokenExpiredError':
return res.status(401).json({ message: '토큰이 만료되었습니다.' });
case 'JsonWebTokenError':
return res.status(401).json({ message: '토큰이 조작되었습니다.' });
default:
return res
.status(401)
.json({ message: error.message ?? '오류 확인좀' });
}
}
}
이 인증 코드에서 문제가 생긴 것 같지는 않았기에 아마 내가 작성한 코드 가운데에서 문제가 생겼을 것으로 여겨진다.
어느 자리에서 문제가 생겼을까 보니까 대부분 알파벳이 하나씩 틀려 있는 문제였다.
문제는 그걸 하나씩 수정할 때마다 다른 곳에서 문제가 생겨서, 하나를 수정할 때마다 다른 곳도 다 수정을 해야 하는 문제가 생겼다.
위기
문제들을 해결하고 보니 벌써 목요일이 되어 있었다. 여기서 아이템이나 캐릭터 수정도 해야 하는데 그것들을 할 시간이 촉박했다.
그래서 작업을 하는데 여기에서도 당연하다는 것처럼 문제가 발생했다. 다시 토큰 문제, 알파벳 문제, 아니면 어딘가 크래시 되었다는 문제……
절정
기본 기능이 완료되었다고 생각되고 도전 과제들을 해보려는 찰나, 다시 문제가 터졌다.
과제 중에 특정 옵션을 통해 캐릭터가 돈을 버는 코드를 작성할 일이 있었는데 그 코드에서 위의 변수 값들이 값을 받지 못하는 사태가 터진 것이다.
router.patch('/characters/:characterId/get_money', logincheck, async (req, res, next) => {
try {
const {userId} = req.userId;
const { characterId } = req.params;
const { money } = req.body;
const islogin = req.islogin;
if(!islogin)
{
return res.status(404).json({error : "로그인 안 됨."})
}
const findcharacter = await prisma.userCharacters.findFirst({
where: {
charId: +characterId
}
});
console.log(characterId)
console.log(money);
console.log(userId)
if (findcharacter) {
throw new Error("오류 발생");
}
console.log("확인")
const updated = await prisma.userCharacters.update({
where: {
UserId: userid,
charId: characterId
},
data: {
money: (findcharacter.money + Number(money))
}
})
console.log("확인")
return res
.status(200)
.json({ data: updated });
}
catch (err) {
return res
.status(404)
.json({ message: "캐릭터 정보 수정이 안 되었습니다." });
}
})
결말
해당 문제는 어이 없게도 선언을 안 해놓은 것 때문이었다. 토큰을 받아오는 미들웨어를 복사하는 과정에서 userid를 반환하는 걸 지운 모양이라
거의 프로젝트 막바지까지 확인하다가 피드백 받으니까 그제서야 찾을 수 있게 되었다.
허무하고 열 받아서 지금 죽을 것만 같다. 이런 게 코딩이니까 참는 수 밖에 없겠지.
오늘 끝나면 잠이나 좀 더 자고 싶다.