오늘은 게시판 CRUD 과제에서, 회원 로그인 및 인증 api를 access/refresh token을 이용하여 인증 middleware를 업그레이드 했다.
api를 모두 짜고, thunder client에서 테스트를 하고 싶었는데, 도무지 req.cookies 값을 넣어주는 방법을 찾지를 못했다.
- 사용자가 로그인을 하면 서버에서는 accessToken과 refreshToken을 발급해서 res.cookie로 클라에 넘겨준다.
- 쿠키로 토큰 값을 전달 받은 클라는 사용자가 인증이 필요한 서비스를 사용할때마다 저장해서 가지고 있던 토큰이 담기 쿠키를 req.cookies로 서버에 날린다.
- 서버에서는 cookie-parser 미들웨어를 사용해서 req.cookies에 담긴 토큰 값을 가져온다.
- 프론트 없이 서버만 만들고 있는 나의 입장에서, thunder client를 통해 req 값을 날려줘야 하는데, 이게 은근히 자료도 잘 안나오고 어려웠다.
// 로그인 api
router.post("/login", async (req, res) => {
try {
const { nickname, password } = await postAuthSchema.validateAsync(req.body);
const user = await Users.findOne({ where: { nickname } });
if (!user || password !== user.password) {
res
.status(412)
.send({ errorMessage: "닉네임 또는 패스워드를 확인해주세요." });
return;
}
const accessToken = createAccessToken(user.userId);
const refreshToken = createRefreshToken();
console.log("typeof token", typeof accessToken);
tokenObject[refreshToken] = user.userId;
res.cookie("accessToken", accessToken); // 토큰을 발행해 res.cookie로 날린다.
res.cookie("refreshToken", refreshToken); // 토큰을 발행해 res.cookie로 날린다.
return res
.status(200)
.send({ message: "Token이 정상적으로 발급되었습니다." });
} catch (err) {
console.log(err);
if (err.name === "CustomError") {
return res.status(err.status).send({ errorMessage: err.message });
} else
return res
.status(400)
.send({ errorMessage: "요청한 데이터 형식이 올바르지 않습니다." });
}
});
// 인증 미들웨어에서 클라에서 날린 req.cookie를 파싱해서 토큰을 인증한다.
async (req, res, next) => {
try {
const { accessToken, refreshToken } = req.cookies; // 요 값을 전달하기 위해 썬드 클라이언트의 여러가지 방법을 찾아보았다.
if (!accessToken || !refreshToken) {
res.status(401).send({ errorMessage: "로그인 후 이용 가능합니다." });
return;
}
const isAccessTokenValid = validateAccessToken(accessToken);
const isRefreshTokenValid = validateRefreshToken(refreshToken);
if (!isRefreshTokenValid)
return res
.status(419)
.json({ message: "Refresh Token이 만료되었습니다." });
if (!isAccessTokenValid) {
const accessTokenId = tokenObject[refreshToken];
console.log("tokenObject", tokenObject);
if (!accessTokenId)
return res.status(419).json({
message: "Refresh Token의 정보가 서버에 존재하지 않습니다.",
});
const newAccessToken = createAccessToken(accessTokenId);
res.cookie("accessToken", newAccessToken);
return res.json({ message: "AccessToken을 새롭게 발급하였습니다." });
}
try {
const { userId } = getAccessTokenPayload(accessToken);
await Users.findOne({
where: { userId },
attributes: { exclude: ["password"] },
}).then((user) => {
res.locals.user = user;
next();
});
} catch (err) {
res.status(401).send({ errorMessage: "로그인 후 이용 가능합니다." });
}
} catch (err) {
console.log(err);
return res
.status(400)
.send({ errorMessage: "알 수 없는 에러가 발생했습니다." });
}
};
VS Code Thunder Client에서 cookie를 헤더에 보내는 방법
1. respose header에 서버가 클라로 날린 set-cookie의 값 (accessToken=~~~~~/, refreshToken=~~~~~~/)을 복사한다.

2. thunder client 메뉴 바에서 Env 탭 > cookie를 클릭한다.

3. 아까 위에서 로그인 하면서 만든 토큰 값(set-cookie)을 환경 변수로 저장해준다.
- 이때, 꼭 변수명을 cookie로 저장해야 한다.

4. 다시, thunder client 메뉴 바에서 Activity 탭을 클릭하고, api 테스트 화면으로 돌아온다.

5. Http Headers 탭으로 가서, header = cookie, value에 {{cookie}}라고 해주고, value 탭에 초록색 불이 들어오는 것을 확인해야 한다.

이렇게 설정하면 thunder client에서 heaer에 쿠키로 토큰 값을 담아 보내기 성공!
그런데, 저 쿠키값을 json 형식으로 받아 사용하려면, 꼭 cookie-parser 미들웨어를 설치하고, 라우터 동작 전에 cookie-parser를 불러 줘야 한다. 아래는 내 app.js 파일의 최상단 구성이다.
- 터미널에서 아래 명령을 입력해 cookie-parser미들웨어를 다운로드 한다.
npm i cookie-parser
- app.js 파일 상단에 아래 코드를 넣어서, 미들웨어를 동작시킨다. 이때, 반드시 cookie-parser를 이용하는 router 미들웨어 위에 쿠키파서 미들웨어 동작 명령을 넣어 줘야 한다.
- 미들웨어는 선언한 순서대로 동작하기 때문에!!
- 그러니까 항상 최상단에 필요한 모든 미들웨어를 선언해두고 가자.

const express = require("express");
const app = express();
const cookieParser = require("cookie-parser");
app.use(cookieParser());'항해99_10기 > 105일의 TIL & WIL' 카테고리의 다른 글
| [4주차] [20221208] node.js의 require() 작동 방식 (0) | 2022.12.08 |
|---|---|
| [4주차] [20221207] express에서 Router : Middleware와 Router (0) | 2022.12.07 |
| [4주차] [20221205] Joi validation & Sequelize를 이용한 mySQL 설정 (0) | 2022.12.06 |
| [3주차 WIL] 2022.11.28 ~ 2022.12.03 회고 (0) | 2022.12.04 |
| [4주차][20221203] node.js에서 mySQL을 사용하기 위해 알아야 하는 것들 : Sequelize, Migration, Model (0) | 2022.12.04 |