엘리스 1차 프로젝트 도중 문제가 생겼다.
제공받은 스켈레톤 코드 중 userAuthRouter.get("/user/current", ...)
의 response.body를 확인하기 위해 Postman으로 테스트를 해보았더니 아래와 같은 결과가 나왔다.
해당 라우터는 로그인 되어 JWT토큰을 부여받은 사용자에 대한 User info 데이터를 보내는 역할을 한다.
이 블로그를 참고하여 Headers에 로그인 된 사용자의 JWT를 같이 보냈으나 "해당 이메일은 가입 내역이 없습니다. 다시 한번 확인해 주세요." 문장이 받아졌다.
결국 코치님께 도움을 요청했고 다음과 같은 답변을 받았다.
처음 답변을 받았을 때 '역으로 추적' 하는 방법이 어떤 의미인지 전혀 몰랐는데, 알고보니 에러가 나온 곳에 console.log을 찍어보는 방법이었다.
import is from "@sindresorhus/is";
import { Router } from "express";
import { login_required } from "../middlewares/login_required.js";
import { userAuthService } from "../services/userService.js";
....
userAuthRouter.get(
"/user/current",
// login_required,
async function (req, res, next) {
try {
const user_id = req.currentUserId;
2️⃣ console.log(user_id)
const currentUserInfo = await userAuthService.getUserInfo({
user_id,
});
1️⃣ console.log(currentUserInfo)
if (currentUserInfo.errorMessage) {
throw new Error(currentUserInfo.errorMessage);
}
res.status(200).send(currentUserInfo);
} catch (error) {
next(error);
}
}
);
먼저 1번 자리에 console.log(currentUserInfo)
을 넣어 터미널에 currentUserInfo 변수를 출력해보았다. → { errorMessage: "해당 이메일은 가입내역이 없습니다 ~~" }
이 에러는 userService.js에서 정의한 getUserInfo()
메서드 코드를 참고했을 때, DB에서 user_id를 찾지 못한 경우 반환되는 에러이다.
2번 자리에 다시 console.log(user_id)
을 찍어보았다. → undefined 가 나왔다.
분명 JWT을 헤더에 전달했음에도 불구하고 user_id를 찾지 못한 이유는 무엇일까
그러다 문득, user_id는 req.currentUserId을 의미하고 req.currentUser은 login_required.js에서 선언된 변수니까 혹시 get 호출할 때 login_required을 주석처리해서 에러가 나는 것이 아닐까 라는 생각이 들었다.
login_required은 로그인한 사용자에게 JWT토큰을 부여하는 함수인데, userToken과 secretKey를 통해 토큰의 유효성을 검증하고 검증된 user_id를 req.currentUserId에 전달하는 역할을 한다.
// login_required.js
import jwt from "jsonwebtoken";
function login_required(req, res, next) {
// request 헤더로부터 authorization bearer 토큰을 받음.
const userToken = req.headers["authorization"]?.split(" ")[1] ?? "null";
// console.log(userToken)
...
// 해당 token 이 정상적인 token인지 확인 -> 토큰에 담긴 user_id 정보 추출
try {
const secretKey = process.env.JWT_SECRET_KEY || "secret-key";
const jwtDecoded = jwt.verify(userToken, secretKey);
const user_id = jwtDecoded.user_id;
req.currentUserId = user_id;
next();
}
...
}
export { login_required };
Postman으로 API테스트를 할 때는 login_required을 라우터 함수에 인자로 추가해주면 "로그인한 유저만 사용가능한 서비스입니다" 문장이 받아져 response.body를 확인할 수 없어서 login_required을 주석 처리한 후 테스트를 해오고 있었기 때문에 login_required을 주석 해제한 후 테스트하는 방법을 쉽게 생각해내지 못했던 것이다.
userAuthRouter.get() 함수에서 login_required 주석을 해제한 후 테스트해보았더니, 로그인된 현재 사용자의 정보가 잘 출력되었다.
에러가 났을 때는 console.log을 사용하여 에러를 역추적해보자. 그럼 해결방법을 더욱 수월하게 찾을 수 있을 것이다.
※ 포스트 그림 만들기 출처 : 개발진스