문제 발생
기존의 코드에서는 API가 실행되기 전에 토큰이 유효한지 검사하고, 그 결과를 받아서 결과에 따라 처리되었다.
=> 하지만 이렇게 하니까 중복되는 코드 발생
기존의 코드
router.post(
"/",
verifyAccessToken,
verifyRefreshToken,
async (req: any, res: Response, next: NextFunction) => {
//아래의 부분 반복
if (req.token === "login again") {
res.json("login again");
} else if (req.token === "refresh ok") {
await Follow.create({
user_id: req.body.user_id,
follower_id: currentUser,
}).then((result) => {
res.status(201).json(result);
});
}
}
);
⇒ 에러발생이 발생했을때 미들웨어 코드에서 미리 끝내주지 않으면, 그 미들웨어를 사용할때마다 그다음 코드에서 에러에 대한 처리를 반복적으로 해주어야한다.
⇒ 즉 코드가 계속 중복된다는 뜻이다. 따라서 이를 방지하기위해서 토큰 검증 미들웨어 코드에서 끝낼 필요가 있다.
해결과정
📄 refresh token 검증 미들웨어 수정
=> catch에 req.token = “login again” 대신 return res.status(500).send({ message: "login again" }) 넣어줌
try {
jwt.verify(token, process.env.REFRESH_TOKEN_SECRET);
req.token = "refresh ok";
req.email = decoded.email;
} catch (error: any) {
return res.status(500).send({ message: "login again" });
}
next();
⇒ refreshToken이 만료되면 서버에서 500번 에러를 던져주는데 이 경우 클라이언트 요청이 거부되기때문에 res.status(500).send({ message: "login again" }) 이부분도 실행 안됨.
📄 access token 검증 미들웨어
=> return res.status(419).json({code: 419,message: "토큰이 만료되었습니다.",}); 넘겨줌.
accessToken이 만료되면 그 다음 코드로 넘어가지 않는다
try {
let decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
console.log(token);
req.email = decoded.email;
console.log(decoded);
} catch (error: any) {
return res.status(419).json({
code: 419,
message: "토큰이 만료되었습니다.",
});
}
next();
axios interceptor에 status번호에 따라서 에러 처리 (프론트)
function (error: any) {
console.log(error.response.data);
console.log(error.response.status);
if (error.response.status === 419) {
console.log("재발급 필요");
customAxios.get("/refreshTokenRequest").then((res) => {
window.alert("엑세스토큰 재발급 완료");
});
}
if (error.response.status === 500) {
console.log("로그인이 만료되었습니다");
alert("재로그인 필요");
dispatch(changeState(false));
const navigate = useNavigate();
navigate("/");
}
}
코드를 수정하면서 발견한 문제점
- axios요청을 할때 header에 들어가는 accessToken이 업데이트가 안됨,
let accessToken = cookie.load("accessToken");
const customAxios = axios.create({
baseURL: "<http://localhost:1234/>",
headers: {
Authorization: `Bearer ${accessToken}`,
},
⇒ 처음 accessToken을 쿠키에서 가져온다음 요청을 보낼때마다 같은 토큰만 보냄. 업데이트가 안됨.
customAxios.interceptors.request.use(
function (config) {
// 요청 바로 직전
// axios 설정값에 대해 작성합니다.
let accessToken = cookie.load("accessToken");
if (accessToken) {
console.log(accessToken);
config.headers.common["Authorization"] = `Bearer ${accessToken}`;
}
return config;
},
function (error) {
console.log(error);
// 요청 에러 처리를 작성합니다.
return Promise.reject(error);
}
);
⇒ 요청 직전에 accssToken을 받아와서 토큰이 업데이트되어도 바뀐 값이 header에 담김.
하나하나씩 console.log를 찍어보면서 데이터가 제대로 업데이트되고 있는지, 제대로 전송되고 있는지 확인하는게 중요하다는 것을 느낌.
'sns 프로젝트' 카테고리의 다른 글
상태관리 도입해서 전역 변수 관리하기(Redux, React Query) (0) | 2024.01.21 |
---|---|
회원가입, 로그인 폼 만들기(validation 유효성 체크, React Hook Form) (0) | 2024.01.21 |
회원가입, 로그인 기능 구현(JWT) (1) | 2024.01.21 |
백엔드 개발 환경 설치 과정(Nodejs, express, Sequelize), CORS해결 (0) | 2024.01.21 |
개인 sns 프로젝트 'NWITTER' 소개 (0) | 2024.01.21 |