๋ค๋ฅธ ์ฌ์ดํธ์์ ์ ์ ๊ฐ ๋ณด๋ด๋ ์์ฒญ์ ์กฐ์ํ๋ ๊ณต๊ฒฉ. ์์๋ก๋ ์ด๋ฉ์ผ์ ์ฒจ๋ถ๋ ๋งํฌ๋ฅผ ๋๋ฅด๋ฉด ๋ด ์ํ๊ณ์ข์ ๋์ด ๋น ์ ธ๋๊ฐ๋ ๋ฐฉ์์ ํดํน ๋ฑ์ด ์๋ค.
ํด์ปค๋ ๋ง๊ทธ๋๋ก ๋ค๋ฅธ ์ฌ์ดํธ์ ์์ผ๋ฏ๋ก, ์๋ต ๊ฐ์ฒด์ ๋ด๊ธด ์ ๋ณด์์ฒด๋ฅผ ํ์ทจํ ์๋ ์์ด์, ์์ฒญ์ ์กฐ์ํ๋ ๊ฒ์ด๋ค.
์ธ์ ๊ธฐ๋ฐ ์ธ์ฆ์ ์๋ฒ์ ๋ถ๋ด์ ์ค๋ค. ๋งค๋ฒ ์ธ์ฆ์ ํ ๋๋ง๋ค DB๋ฅผ ์ดํด์ผํ๊ณ , ์ฐ์ ๋ฐ์ดํฐ ์ ์์ฒด๊ฐ ์ฃผ๋ ๋ถ๋ด๋ ์กด์ฌํ๋ค. ๊ทธ๋ ๋ค๋ฉด ์์ฐ์ค๋ฝ๊ฒ ํด๋ผ์ด์ธํธ์๊ฒ ์ด ๋ถ๋ด์ ๋๊ฒจ์ค ์๋ ์์๊น, ๊ณ ๋ฏผํ ๊ฒ์ด๋ค. ๊ทธ๋ ๊ฒ ๊ณ ์๋ ๊ฒ์ด ๋ฐ๋ก ํ ํฐ ๊ธฐ๋ฐ ์ธ์ฆ์ด๋ค!
์ธ์ฆ์ ํต์ฌ์ ์ด๋ป๊ฒ ํด๋ผ์ด์ธํธ์ ๋ณด๊ดํ ์ ์์ง? ํ๋ ๊ณ ๋ฏผ์ด ํ ์ ์์ง๋ง, ํ ํฐ์ ์ํธํ๋์ด ์๋ค๋ ์ ์ ๊ธฐ์ตํด์ผ ํ๋ค.
ํ ํฐ์ ๊ตฌ์กฐ๋ฅผ ์ดํด๋ณด์.
๊ฐ์ฅ ๋ฒ์ฉ์ ์ผ๋ก ์ฌ์ฉ๋๋ ํ ํฐ์ธ jwt ๊ณต์ ํ์ด์ง์ ๋ค์ด๊ฐ๋ณด๋ฉด ๋ฉ์ธํ์ด์ง์์ ๋ถํฐ ์์ ๊ฐ์ ํ๋ฉด์ ๋ณผ ์ ์๋ค.
์ด ๋ถ๋ถ์ด ๋ฐ๋ก ํ ํฐ์ ๊ตฌ์กฐ๋ฅผ ์ค๋ช
ํ๊ณ ์๋ค.
axios
.post("https://localhost:4000/login", {
userId: this.state.userId,
password: this.state.password,
})
// ์๋ ์ฝ๋์์ userInfo๋ ํด๋ผ์ด์ธํธ์์ ๋ณด๋ธ ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ก DB์์ ์กฐํํ ์ ๋ณด
let userInfoWithoutPW = Object.assign(userInfo.dataValues);
// ํจ์ค์๋๋ ์ญ์ ํด์ฃผ์ด์ผ ํ๋ค. ๋ฏผ๊ฐํ ์ ๋ณด์ด๋ฏ๋ก!
delete userInfoWithoutPW.password;
const accessToken = jwt.sign(userInfoWithoutPW, process.env.ACCESS_SECRET, {
expiresIn: "1h",
});
const refreshToken = jwt.sign(
userInfoWithoutPW,
process.env.REFRESH_SECRET,
{
expiresIn: "7d",
}
);
res.cookie("refreshToken", refreshToken);
res.json({
data: { accessToken },
message: "ok",
});
jwt.sign()
๋ฉ์๋์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋ค์ด๊ฐ ์ ๋ณด๋ ์์ ๋กญ๊ฒ ๋ฃ์ด๋ ์ ์๋ค. accessToken๊ณผ refreshToken์ ๋์ผํ ์ ๋ณด๋ฅผ ๋ฃ์ ํ์๋ ์๋ค. ๋ชจ์ชผ๋ก ์ ์ ๋ฅผ ๊ตฌ๋ถํ ์ ์๋ ๊ฐ์ด๋ฉด ๋๋ค. this.props.issueAccessToken(res.data.data.accessToken);
axios({
method: "get",
url: "https://localhost:4000/accesstokenrequest",
headers: { authorization: "Bearer " + this.props.accessToken },
}).then((res) => {
this.setState(res.data.data.userInfo);
});
Bearer
๋ฅผ ๋ถ์ฌ์ฃผ๋ ์ด์ ๋ accessToken์ผ๋ก bearer Token์ ๋๊ฒจ์ค๋ค๋ ์๋ฏธ์ด๋ค. ์ฌ์ค ์์ง Bearer Token์ด ๋ฌด์์ธ์ง ์ ํํ ์ดํดํ์ง๋ ๋ชปํ์ผ๋, Basic๊ณผ Bearer๋ผ๋ ํฌ๋งท์ด ์กด์ฌํ๊ณ , Basic์ ๋ณ๋์ key์์ด ๋ณตํธํ๊ฐ ๊ฐ๋ฅํ ์์ ํ์ง ์์ ๋ฐฉ์์ด๋ผ๋ ์ , ๊ทธ๋ฆฌ๊ณ "๋ณดํธ๋ ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ ๊ถํ์ ๋ถ์ฌ๋ฐ๊ธฐ ์ํด ์ ์ํ๋ ์ ์ผํ ์์
์ด ํ ํฐ์ ์ ๋ฌํ๋ ๊ฒ ๋ฟ"์ผ ๋ ํด๋น ํ ํฐ์ bearer ํ ํฐ์ด๋ผ ํ๋ค๋ ๊ฒ ์ ๋ ์ดํดํ๋ค. if (!req.headers.authorization) {
res.status(401).send({ data: null, message: "invalid access token" });
} else {
let token = req.headers.authorization.split("Bearer ")[1];
let userInfo = jwt.verify(token, process.env.ACCESS_SECRET);
delete userInfo.iat;
res.status(200).send({ data: { userInfo }, message: "ok" });
}
1) ๋ฌด์ํ์ฑ & ํ์ฅ์ฑ: ํด๋ผ์ด์ธํธ๊ฐ ์ธ์ฆ ์ ๋ณด๋ฅผ ๊ฐ๊ณ ์์ผ๋ฏ๋ก, ์๋ฒ๊ฐ ์ฌ๋ฌ ๊ฐ์ธ ์๋น์ค๋ผ ํ๋๋ผ๋, ํ๋์ ํ ํฐ์ผ๋ก ํด๊ฒฐ ๊ฐ๋ฅํ๋ค.
2) ์์ ์ฑ: ์ํธํ ํค๋ฅผ ๋ ธ์ถํ ํ์๊ฐ ์๋ค.
3) ์ด๋์๋ ์์ฑ ๊ฐ๋ฅ: ํน์ ํ ์๋ฒ๊ฐ ๊ผญ ํ ํฐ์ ๋ง๋ค ํ์๊ฐ ์๋ค.
4) ๊ถํ ๋ถ์ฌ์ ์ฉ์ด: ํ ํฐ์ payload ์์ ์ด๋ค ์ ๋ณด์ ๋ํ ์ ๊ทผ์ด ๊ฐ๋ฅํ์ง ์์๋ก ์ ์๊ฐ ๊ฐ๋ฅํ๋ค. (๋ถ๋ถ์ ์ ๊ทผ๊ถํ์ ์ค ์ ์๋ค)
token์ด ํ์ทจ๋ ๊ฒ์ ๋ํ ์ฐ๋ ค๋ก, token์ ๋ ๋ฐ๊ธํ์ฌ, access token๊ณผ refresh token์ผ๋ก ์ฌ์ฉํ๋ค. access token์๋ ์งง์ ์ ํจ๊ธฐ๊ฐ์ ์ค ํ์ทจ๋๋๋ผ๋ ์ค๋ซ๋์ ์ฌ์ฉ๋ ์ ์๋๋กํ๊ณ , access token์ ๊ธฐํ๊ธฐ ๋ง๋ฃ๋๋ฉด, refresh token์ผ๋ก ์ access token์ ๋ฐ๊ธ๋ฐ๋๋ค.
๊ทธ๋ฌ๋ refresh token๋ ํ์ทจ๋ ์ ์๊ณ , ๋ณด์์ด ์์ฒญ ์ค์ํ ์๋น์ค๋ผ๋ฉด refresh token์ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ๋ ์๋ค๊ณ ํ๋ค! (๊ทธ๋ผ ๊ธฐํ ๋ง๋ฃ๋๋ฉด ๋งค๋ฒ ์๋ก access token ๋ฐ๊ธ๋ฐ์...?)