์ฟ ํค๋ ๋ธ๋ผ์ฐ์ ๊ฐ ๊ด๋ฆฌํ๋ ์์ ๋ฐ์ดํฐ ์กฐ๊ฐ์ผ๋ก, ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์๊ฒ ์๋ตํ ๋ ์ ์ฅ์ ์์ฒญํ๊ณ , ์ดํ ํด๋ผ์ด์ธํธ๊ฐ ํด๋น ์ฌ์ดํธ์ ์ฌ์ ์ํ ๋ ์๋์ผ๋ก ํจ๊ป ์ ์ก๋๋ ๋ฐ์ดํฐ์ด๋ค. ์ฆ, ์น์ฌ์ดํธ๊ฐ ์ฌ์ฉ์์ ๋ํด ๊ธฐ์ตํ๊ณ ์ถ์ ๊ฑธ ์ด์ง ์ ์ด๋๋ ๋ฉ๋ชจ์ด๋ค.
์๋ฒ: ์ด ์ฌ์ฉ์ ๋ก๊ทธ์ธํ๋ค? ๊ทธ๋ผ ๋ฉ๋ชจ ์ ์!
Set-Cookie: isLoggedIn=true
๋ธ๋ผ์ฐ์ ๋ ์ด๊ฑธ ๋ฐ์์ ์ ์ฅํด๋๋ค.
๋ค์ ๊ทธ ์ฌ์ดํธ์ ๋ค์ด๊ฐ๋ฉด, ๋ธ๋ผ์ฐ์ ๊ฐ
Cookie: isLoggedIn=true
์ด๋ฐ ์์ผ๋ก ์๋์ผ๋ก ์ฟ ํค๋ฅผ ๋ณด๋ธ๋ค.
๊ทธ๋ฌ๋ฉด ์๋ฒ๋
"์ค! ๋ก๊ทธ์ธ ๋์ด ์๋ค~"
ํ๊ณ ๋ฐ๋ก ์๋น์ค๋ฅผ ๋ณด์ฌ์ค ์ ์๋ค.
๋๊ตฌ๋ ๋ณผ ์ ์๋ ๋ฉ๋ชจ๋ผ ๋ณด์์ ์ฃผ์ํด์ผํ๋ค.
-> ์ค์ํ ์ฟ ํค์๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ชป ๋ณด๊ฒ ์ ๊ทธ๋ HttpOnly ์ต์
์ ๋ถ์ธ๋ค.
-> https์์๋ง ์ฐ๊ฒ ํ๋ Secure ์ต์
์ ์ฐ๊ธฐ๋ ํ๋ค.
์ธ์ ์ ํด๋ผ์ด์ธํธ(์ฌ์ฉ์)์ ์๋ฒ ๊ฐ์ ์ฐ๊ฒฐ ์ํ๋ฅผ ์ผ์ ์๊ฐ ๋์ ์ ์งํ๋ฉฐ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ผ๋ก, ์๋ฒ๊ฐ ์ฌ์ฉ์๋ณ ์ ๋ณด๋ฅผ ๊ธฐ์ตํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ธฐ์ ์ด๋ค.
์ฌ์ฉ์: ์ ๋ก๊ทธ์ธํ ๊ฒ์! (์์ด๋, ๋น๋ฐ๋ฒํธ ์ ์ก)
์๋ฒ๋ ์ ๋ณด๋ฅผ ํ์ธํ ๋ค:
์๋ฒ: ๋ก๊ทธ์ธ ์ฑ๊ณต! ์ด ์ฌ์ฉ์๋ฅผ ๊ธฐ์ตํด์ผ์ง.
(์๋ฒ ์์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ , ์ธ์
ID๋ฅผ ๋ง๋ ๋ค)
Set-Cookie: sessionId=abc123; HttpOnly
๋ธ๋ผ์ฐ์ ๋ sessionId๋ฅผ ์ฟ ํค๋ก ์ ์ฅํ๋ค.
์ฌ์ฉ์๊ฐ ๋ค์ ํ์ด์ง๋ฅผ ์ด๋ํ๊ฑฐ๋ ์๋ก๊ณ ์นจํ ๋:
Cookie: sessionId=abc123
์ด๋ ๊ฒ ๋ธ๋ผ์ฐ์ ๊ฐ ์ธ์ ID๋ฅผ ์๋์ผ๋ก ์๋ฒ์ ๋ณด๋ธ๋ค.
์๋ฒ๋ ์ธ์ ID abc123์ ํ์ธํ๊ณ ,
์๋ฒ: ์, ์ด๊ฑด ์๊น ๋ก๊ทธ์ธํ๋ ์ฌ์ฉ์๊ตฌ๋!
์ ์ฅํด๋๋ ์ ๋ณด๋ฅผ ๊บผ๋ด์์ ๋ก๊ทธ์ธ ์ํ๋ฅผ ์ ์งํด์ค๋ค.
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์์ํ๊ฑฐ๋, ์ผ์ ์๊ฐ์ด ์ง๋๋ฉด
์๋ฒ: ์ด์ ์ด ์ธ์
์ ๋ง๋ฃ์ผ! ์ฌ์ฉ์ ์ ๋ณด ์ญ์ !
์ธ์ ์ด ์ฌ๋ผ์ง๊ณ , ์๋ ๋ก๊ทธ์์์ฒ๋ผ ์ฒ๋ฆฌ๋๋ค.
ํ ํฐ์ ์ฌ์ฉ์์ ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ด์ ๋ฌธ์์ด ๋ฐ์ดํฐ๋ก, ์๋ฒ์ ํด๋ผ์ด์ธํธ๊ฐ ์ธ์ฆ ์ํ๋ฅผ ์ ์งํ๋ ๋ฐ ์ฌ์ฉ๋๋ค. ์ด ์ค์์ ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ๋ฐฉ์์ด ๋ฐ๋ก JWT (JSON Web Token) ์ด๋ค.
JWT๋ ์ฌ์ฉ์์ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ์ธ์ฝ๋ฉํ ํ ํฐ์ผ๋ก, ์๋ฒ๊ฐ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ๋ณ๋๋ก ์ ์ฅํ์ง ์์๋, ํ ํฐ๋ง ๋ณด๊ณ ์ฌ์ฉ์๋ฅผ ์ธ์ฆํ ์ ์๊ฒ ํด์ฃผ๋ ๋ฌด์ํ ์ธ์ฆ ๋ฐฉ์์ด๋ค.
์ฌ์ฉ์๊ฐ ์์ด๋/๋น๋ฐ๋ฒํธ๋ก ๋ก๊ทธ์ธ ์์ฒญ์ ๋ณด๋ธ๋ค.
POST /login
{
"username": "user1",
"password": "1234"
}
์๋ฒ๋ ์ฌ์ฉ์๋ฅผ ์ธ์ฆํ๊ณ , ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ด์ JWT๋ฅผ ๋ฐ๊ธํ๋ค.
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6..."
}
ํด๋ผ์ด์ธํธ๋ ์ด JWT๋ฅผ ๋ก์ปฌ์คํ ๋ฆฌ์ง ๋๋ ์ธ์ ์คํ ๋ฆฌ์ง์ ์ ์ฅํ๋ค.
localStorage.setItem("token", receivedToken);
ํ๋ก ํธ์๋๋ ์๋ฒ์ ์์ฒญํ ๋๋ง๋ค JWT๋ฅผ ํค๋์ ํฌํจํด์ ๋ณด๋ธ๋ค.
GET /user/info
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
์๋ฒ๋ ํ ํฐ์ด ์ ํจํ์ง ํ์ธํ๊ณ , ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์ถ์ถํด์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ค.
๋ง๋ฃ๋ ํ ํฐ์ด๋ฉด 401 Unauthorized ์๋ตํ๊ณ ,
์์กฐ๋ ํ ํฐ์ด๋ฉด ์๋ช
๋ถ์ผ์น๋ก ์์ฒญ ๊ฑฐ๋ถํ๋ค.
| ๊ตฌ๋ถ | ์ฟ ํค (Cookie) | ์ธ์ (Session) | ํ ํฐ (Token, ํนํ JWT) |
|---|---|---|---|
| ์ ์ฅ ์์น | ํด๋ผ์ด์ธํธ(๋ธ๋ผ์ฐ์ ) | ์๋ฒ | ํด๋ผ์ด์ธํธ (์ฃผ๋ก ๋ก์ปฌ์คํ ๋ฆฌ์ง, ์ธ์ ์คํ ๋ฆฌ์ง) |
| ๋ณด์์ฑ | ๋ฎ์ (์กฐ์ ๊ฐ๋ฅ) | ๋์ (์๋ฒ ์ ์ฅ) | ๋น๊ต์ ๋์ (์๋ช ๊ธฐ๋ฐ) |
| ์ ์ง ๋ฐฉ์ | ์๋ ์์ฒญ ์ ํฌํจ๋จ (header์ ์๋ ํฌํจ) | ์๋ฒ์์ ์๋ณ ์ ๋ณด ์ ์ฅ ํ ์ฟ ํค๋ก ID ์ ๋ฌ | ํด๋ผ์ด์ธํธ๊ฐ ๋งค ์์ฒญ๋ง๋ค ํ ํฐ์ ์๋์ผ๋ก ์ ๋ฌ |
| ์ฌ์ฉ ๋ฐฉ์ | ์ํ ๊ธฐ๋ฐ (์ธ์ ID๋ฅผ ๋ด์) | ์ํ ๊ธฐ๋ฐ (์ธ์ ID๋ก ์๋ฒ์์ ์ํ ์ ์ง) | ๋ฌด์ํ(Stateless) ๋ฐฉ์ (์๋ฒ๋ ํ ํฐ๋ง ํ์ธ) |
| ํน์ง | ํฌ๊ธฐ ์ ํ (4KB), ์๋ ์ ์ก | ์๋ฒ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ | ์์ฒด์ ์ธ์ฆ ์ ๋ณด ํฌํจ, ์๋ฒ ๋ถํ ์ ์ |
์ฟ ํคํ ํฐ์ธ์ ๋ค์ด ์ด๋ป๊ฒ ์ด์ฉ๋๋์ง ํ๋ํ๋ ์คํ ๋ฆฌํ ๋ง์ ํ์ ์ ์ดํดํ๊ธฐ ํธํ๋ค์! ์๋ง ๋ก๊ทธ์ธ์ ๊ตฌํํ๋ค๋ฉด JWT๋ฅผ ์ฌ์ฉํ ๊ฐ๋ฅ์ฑ์ด ์ ์ผ ๋์ํ ๋ฐ, ๊ธฐํ์ฝ์ค ๋์ ๋ฐฑ์๋๋ ๊ฐ๋จํ๊ฒ ์๊ธฐํ๋ฉด์ ๋ก๊ทธ์ธ ๊ณผ์ ์ ๋ฏธ๋ฆฌ ๊ฑฐ์ณ๋ด๋ ์ข์๊ฑฐ ๊ฐ์์ฌ