ํด์ ํ ์ด๋ธ์์ ๋ค๋ฃจ์๋ ์ ์ด ์๋ Hash!
ํค(Key) ๊ฐ์ ํด์ ํจ์(Hash Function)๋ผ๋ ์์์ ๋์ ์์ผ ๊ณ์ฐํ ํ ๋์จ ๊ฒฐ๊ณผ๋ฅผ ์ฃผ์๋ก ์ฌ์ฉํ์ฌ ๋ฐ๋ก ๊ฐ(Value)์ ์ ๊ทผํ๊ฒ ํ ์ ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ธ์ฆ์์์ ํด์ฑ์ด๋ ๊ฒฐ๊ตญ ์ด๋ค ๊ฐ์ "์์์ ์ฐ์ฐ"์ ์ ์ฉํด ๋ค๋ฅธ ๊ฐ์ผ๋ก ๋ณํ, ์ฆ ์ํธํํ๋ ๊ณผ์ ์ ๋งํ๋ ๊ฒ์ด๋ผ ํ ์ ์๋ค.
1) ๋ชจ๋ ๊ฐ์ ๋ํด ํด์๊ฐ์ ๊ณ์ฐํ๋๋ฐ ์ค๋ ๊ฑธ๋ฆฌ์ง ์์์ผ ํ๋ค.
2) ์ต๋ํ ํด์ ๊ฐ์ ํผํด์ผ ํ๋ฉฐ, ๋ชจ๋ ๊ฐ์ ๊ณ ์ ํ ํด์ ๊ฐ์ ๊ฐ์ง๋ค.
3) ์์ฃผ ์์ ๋จ์์ ๋ณ๊ฒฝ์ด๋ผ๋ ์์ ํ ๋ค๋ฅธ ํด์ ๊ฐ์ ๊ฐ์ ธ์ผ ํ๋ค.
๊ทธ๋ฌ๋ ์ฌ์ค ์๋ฒฝํ ํด์ฑ ์๊ณ ๋ฆฌ์ฆ, ์๋ฒฝํ ์ํธํ๋ ์๋ค. ๋ฌผ๋ก ํด์ฑํจ์๋ ์ญํจ์๊ฐ ์กด์ฌํ์ง ์๋ ํจ์๋ก ๋ง๋๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด์ง๋ง, ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ธฐ๋กํด๋๊ณ ์ถ์ ํ๋ ๊ฒ๊น์ง ๋ง์ ์๋ ์๋ค. ํด์ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ง๋ค ์ ์๋ ๊ฐ๋ค์ ๋๋์ผ๋ก ์ ์ฅํด๋์ ํ์ธ ๋ ์ธ๋ณด์ฐ ํ
์ด๋ธ
์ด๋ ๊ฒ๋ ์กด์ฌํ๋ค...!
๊ทธ๋์! ์๋ณธ๊ฐ์ ์์๋ก ์ฝ์๋ ๋ณ๋์ ๋ฌธ์์ด์ ์ถ๊ฐํด ๊ธฐ์กด ํด์ ๊ฐ๊ณผ ์ ํ ๋ค๋ฅธ ํด์๊ฐ์ ๋ฐํํด ์๊ณ ๋ฆฌ์ฆ์ด ๋ ธ์ถ๋๋๋ผ๋ ์๋ณธ๊ฐ์ ๋ณดํธํ๋ค. ์ด ๋ ์ถ๊ฐํ๋ ๋ณ๋์ ๊ฐ์ salt๋ผ๊ณ ํ๋ค!
salt๋ ์ฌ์ฌ์ฉํด์๋ ์ ๋๋ฉฐ, ์ฌ์ฉ์ ๊ณ์ ์ ์์ฑํ๊ณ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ ๋๋ง๋ค ์๋ก์ด ์์์ salt๋ฅผ ์ฌ์ฉํด ํด์ฑํด์ผ ํ๋ค. ๋, salt๋ ๋น์ฐํ DB ์ ์ ํ ์ด๋ธ์ ๊ฐ์ด ์ ์ฅํ๋ค!
์ฒ์์ ์ฟ ํค๋ฅผ ํ์ตํ ๋, ์ธ์ฆ๊ณผ ์ฎ์ด์ ํ์ตํ์ด์ ์ฟ ํค๋ฅผ ์ธ์
, ํ ํฐ
๊ณผ ๋น์ทํ๊ฒ ์ธ์ฆ ๋ฐฉ์ ์์ฒด๋ก ์ดํดํ์๋ค. ๊ทธ๋ฌ๋ ์๋ฐํ ๋งํ๋ฉด ์ฟ ํค๋ ์ธ์ฆ ๋ฐฉ์์ด๋ผ๊ธฐ๋ณด๋ค๋ ์๋ฒ์์ ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ๋ฒ ์ค ํ๋์ด๋ค. ๋ค๋ง ์ธ์ฆ ๊ณผ์ ์ ํ์ฉ๋๋ ๊ฒ!
HTTP ์ฟ ํค(์น ์ฟ ํค, ๋ธ๋ผ์ฐ์ ์ฟ ํค)๋ ์๋ฒ๊ฐ ์ฌ์ฉ์์ ์น ๋ธ๋ผ์ฐ์ ์ ์ ์กํ๋ ์์ ๋ฐ์ดํฐ ์กฐ๊ฐ์ ๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ๊ทธ ๋ฐ์ดํฐ ์กฐ๊ฐ๋ค์ ์ ์ฅํด ๋์๋ค๊ฐ, ๋์ผํ ์๋ฒ์ ์ฌ ์์ฒญ ์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ์ ์กํฉ๋๋ค. ์ฟ ํค๋ ๋ ์์ฒญ์ด ๋์ผํ ๋ธ๋ผ์ฐ์ ์์ ๋ค์ด์๋์ง ์๋์ง๋ฅผ ํ๋จํ ๋ ์ฃผ๋ก ์ฌ์ฉํฉ๋๋ค. ์ด๋ฅผ ์ด์ฉํ๋ฉด ์ฌ์ฉ์์ ๋ก๊ทธ์ธ ์ํ๋ฅผ ์ ์งํ ์ ์์ต๋๋ค. ์ํ๊ฐ ์๋(stateless) HTTP ํ๋กํ ์ฝ์์ ์ํ ์ ๋ณด๋ฅผ ๊ธฐ์ต์์ผ์ฃผ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ชจ์ชผ๋ก ์ฟ ํค๋ฅผ ํ์ฉํ๋ฉด ์๋ฒ๋ ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด ์ ์ฅํ ์ ์๊ณ , ๋ ํด๋น ์ ๋ณด๋ฅผ ๋ค์ ๊ฐ์ ธ์ฌ ์๋ ์๋ค! (๋ํ ์ฟ ํค๋ ๋ฐ๋ก ์ญ์ ํ์ง ์์ผ๋ฉด ๊ณ์ํด์ ๋ณด์กด๋๋ค.) ๊ทธ๋ฌ๋ ๋น์ฐํ๊ฒ๋ ์๋ฌด ๋๋ ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ ๊ฒ์ ์๋๋ค. ์ด ์กฐ๊ฑด๋ค์ ๋ํ๋ธ ๊ฒ๋ค์ด ๋ฐ๋ก ์ฟ ํค์ต์ ์ด๋ค!
// example
cookie: {
domain: 'localhost',
path: '/',
maxAge: 24 * 6 * 60 * 10000,
sameSite: 'none',
httpOnly: true,
secure: true,
},
์๋ฒ์ ์ ์ฅํด์ผ ํ ๋ก๊ทธ์ธ, ์ฅ๋ฐ๊ตฌ๋, ๊ฒ์ ์ค์ฝ์ด ๋ฑ์ ์ ๋ณด ๊ด๋ฆฌ
์ฌ์ฉ์ ์ ํธ, ํ ๋ง ๋ฑ์ ์ธํ
์ฌ์ฉ์ ํ๋์ ๊ธฐ๋กํ๊ณ ๋ถ์ํ๋ ์ฉ๋
์ฟ ํค๋ ์ฌ์ค ๊ทธ ์์ฒด๋ก ์ธ์ฆ ์๋จ์ ์๋๋ผ๋ ์ฌ์ค์ ์ดํด๋ณด์๋ค. ๊ฒ๋ค๊ฐ ํด๋ผ์ด์ธํธ์ ์ ๋ณด๋ค์ ์ ์ฅํ๋๋ฐ ์ด๋ ๋ณด์์ ๊ทธ๋ฆฌ ๊ฐ๋ ฅํ ์ ํ์ด ์๋๋ค! ์ด์ ๋ํ ๋์์ผ๋ก ์ฐ๋ฆฌ๋ ์ธ์ ๊ธฐ๋ฐ ์ธ์ฆ์ ์์๋ณผ ๊ฒ์ด๋ค!
์ฟ ํค๊ฐ ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๊ฒ๊ณผ ๋ฌ๋ฆฌ ์ธ์ ๊ธฐ๋ฐ ์ธ์ฆ์์๋ ๋ฐ์ดํฐ๋ค์ ์๋ฒ์ ์์ ํ๊ฒ ์ ์ฅํ๋ค! ์ธ์ ์คํ ๋ฆฌ์ง์ ์ ๋ณด๋ค์ ์ ์ฅํ๊ณ ๋์ ํด๋ผ์ด์ธํธ์๋ ์ธ์ id๋ง์ ์ ๋ฌํด์ฃผ๋ ๊ฒ์ด๋ค! ๋ช ํํ ๋ฐ์ง๋ฉด ์ฌ์ฉ์๊ฐ ์ธ์ฆ์ ์ฑ๊ณตํ ์ํ๊ฐ ์ธ์ ์ ํด๋นํ๊ณ , ์ธ์ ์ด ํ์ฑํ๋๋ฉด ์ธ์ ์์ด๋๊ฐ ๋ฐ๊ธ๋๊ณ , ์ด ์ธ์ ์ฑ๊ณต์ ์ฆ๋ช ํ ์๋จ์ผ๋ก ํด๋ผ์ด์ธํธ๋ ์ธ์ ์์ด๋๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์ฟ ํค์๋ ์ด id๋ง ์ ์ฅ์ ํด์ฃผ๋ ๊ฒ์ด๋ค!
์ธ์ ์คํ ๋ฆฌ์ง๋ฅผ ์ ์ฅํ๋ ๋ฐฉ์์ ๋ค์ํ๋ฐ, 1) ์๋ฒ ์์ฒด์ ์ ์ฅ์ ํ ์๋ ์๊ณ , 2) ํ์ผ๋ก ์ ์ฅ์ ํ ์๋ ์๊ณ , 3) DB์ ์ ์ฅ์ ํ ์๋ ์๋ค. 1)์ ๊ฒฝ์ฐ ์๋ฒ๊ฐ ์ข ๋ฃ๋๋ฉด ์ ๋ณด๋ค์ด ๋ชจ๋ ์ฌ๋ผ์ง๋ค๋ ์ทจ์ฝ์ ์ด ์กด์ฌํ๋ฉฐ, 2)์ ๊ฒฝ์ฐ ๋์์ ์์ ์ด ๋ถ๊ฐํ๋ค๋ ๋จ์ ์ด ์กด์ฌํ๋ค!
axios
.post(
"https://localhost:4000/users/login",
{
userId: this.state.username,
password: this.state.password,
},
{
"Content-Type": "application/json",
withCredentials: true,
}
)
์ฌ๊ธฐ์ ์ ๊น withCredentials์ ๋ํด ์ง๊ณ ๋์ด๊ฐ์! ๊ธฐ๋ณธ์ ์ผ๋ก withCredentials
๋ CORS ์ต์
์ด๋ค. ๊ฐ์ origin์์ httpํต์ ์ ํ๋ ๊ฒฝ์ฐ ์์์ cookie๊ฐ request header์ ๋ค์ด๊ฐ๋ค. ํ์ง๋ง origin์ด ๋ค๋ฅผ ๊ฒฝ์ฐ๋ ๊ทธ๋ ์ง ์๋ค. ์๋์ผ๋ก ์ฟ ํค๋ฅผ ํค๋์ ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค. ์ด๋ ํ์ํ ๊ฒ์ด ํด๋ผ์ด์ธํธ์์๋ withCredentials: true
, ์๋ฒ์์๋ Access-Control-Allow-Credentials : true
์ด๋ค!
req.session.save(function () {
req.session.userId = userInfo.userId;
res.json({ data: userInfo, message: "ok" });
});
ํด๋น ๋ฉ์๋๋ ์ธ์ ์ ๋ค์ ์ ์ฅ์์ ์ ์ฅํ๊ณ , ์ ์ฅ์์ ๋ด์ฉ์ ๋ฉ๋ชจ๋ฆฌ์ ๋ด์ฉ์ผ๋ก ๋ฐ๊พผ๋ค. ์ธ์ ์ ์คํ ์ด์ ์ ์ฅํ๊ณ ๋๋ฉด callback์ผ๋ก ๋๊ฒจ์ค ํจ์๊ฐ ์คํ๋๋ค. ์ด ๋ฉ์๋๋ฅผ ์ฐ์ง ์์ผ๋ฉด, ๋ฐ์ดํฐ๋ฅผ session store์ ์ ์ฅํ๋ ๊ฒ๋ณด๋ค redirect๊ฐ ๋จผ์ ์คํ๋์ด ๋ก๊ทธ์ธ ์ํ๊ฐ ์ ์ง๋์ง ์๋ ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ ์ ์๋ค!
if (!req.session.userId) {
res.status(400).send({ data: null, message: "not authorized" });
} else {
const result = await Users.findOne({
where: { userId: req.session.userId },
}).catch((err) => res.json(err));
res.status(200).json({ data: result, message: "ok" });
}