์ต๊ทผ Google CASA ์ธ์ฆ์ ๋ฐ์ผ๋ฉด์ JWT๋ฅผ ํด๋ช (?)ํด์ผํ ์ผ์ด ๋ง์์ต๋๋ค. ๊ทธ๋ฌ๋ค ๋ณด๋ '์ด๊ฑฐ ํ ๋ฒ ์ ๋๋ก ์ ๋ฆฌํด์ผ๊ฒ ๋ค'๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ์ฌ์ค JWT๋ ๋ง์ ๊ฐ๋ฐ์๊ฐ ์ฌ์ฉํ๊ณ ์์ง๋ง, ์ ๋๋ก ์ดํดํ์ง ๋ชปํ๋ฉด ๋ณด์์ ์ผ๋ก ํฐ ๋ฌธ์ ๊ฐ ๋ ์๋ ์๊ฒ ๋ค๋ ์๊ฐ์ด ๋ค๋๊ตฐ์. ๊ทธ๋์ ์ค๋์ JWT๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง, ์ ๋ง์ด ์ฌ์ฉ๋๋์ง, ๊ทธ๋ฆฌ๊ณ ๋ณด์์ ์ผ๋ก ์ด๋ค ์ ์ ์ฃผ์ํด์ผ ํ๋์ง ํ ๋ฒ์ ์ ๋ฆฌํด๋ณด๊ฒ ์ต๋๋ค! ๐
JWT๋ 3๊ฐ์ง ํํธ๋ก ๊ตฌ์ฑ๋ ๋ฌธ์์ด์
๋๋ค. ์ (.
)์ผ๋ก ๊ตฌ๋ถ๋๋ฉฐ, ๊ฐ๊ฐ ํค๋(Header), ํ์ด๋ก๋(Payload), ์๋ช
(Signature)์ผ๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvbiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT์ ํค๋์๋ ํ ํฐ ํ์ ๊ณผ ์ฌ์ฉ๋ ์ํธํ ์๊ณ ๋ฆฌ์ฆ์ด ํฌํจ๋ฉ๋๋ค.
{
"alg": "HS256",
"typ": "JWT"
}
alg
: ์ฌ์ฉํ ์ํธํ ์๊ณ ๋ฆฌ์ฆ(์: HS256, RS256)typ
: ํ ํฐ ํ์
(JWT)JWT์ ํ์ด๋ก๋์๋ ์ฌ์ฉ์ ์ ๋ณด์ ํ ํฐ์ ๋ง๋ฃ ์๊ฐ ๋ฑ์ด ํฌํจ๋ฉ๋๋ค.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
sub
: ํ ํฐ์ ์ฃผ์ธ (Subject)name
: ์ฌ์ฉ์ ์ด๋ฆiat
: ํ ํฐ์ด ๋ฐ๊ธ๋ ์๊ฐ (Issued At)๐ ์ฃผ์: JWT๋ Base64๋ก ์ธ์ฝ๋ฉ๋๊ธฐ ๋๋ฌธ์, ๋๊ตฌ๋ ์ง ๋์ฝ๋ฉํด์ ๋ด์ฉ์ ๋ณผ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๋น๋ฐ๋ฒํธ ๊ฐ์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ์ ๋ ํฌํจํด์๋ ์ ๋ฉ๋๋ค!
์๋ช (Signature)์ JWT์ ๋ฌด๊ฒฐ์ฑ(Integrity)์ ๋ณด์ฅํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค. ์ฆ, ํ ํฐ์ด ์ค๊ฐ์ ์กฐ์๋์ง ์์๋ค๋ ๊ฒ์ ํ์ธํ๋ ์ญํ ์ ํฉ๋๋ค.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
์๋ช ๋ถ๋ถ์ด ์ ํจํ์ง ์์ผ๋ฉด, ํ ํฐ์ด ๋ณ์กฐ๋์์์ ์๋ฏธํ๋ฏ๋ก ์ธ์ฆ์ด ๊ฑฐ๋ถ๋ฉ๋๋ค.
JWT๊ฐ ์ธ๊ธฐ ์๋ ์ด์ ๋ ๊ฐ๋จํฉ๋๋ค. ์ฌ์ฉํ๊ธฐ ํธ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
1๏ธโฃ ์ํ ๊ด๋ฆฌ๊ฐ ํ์ ์์
JWT๋ ์๋ฒ๊ฐ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ๋ฐ๋ก ์ ์ฅํ ํ์๊ฐ ์์ต๋๋ค. ์์ ๋ฐฉ์์ฒ๋ผ ์ฌ์ฉ์์ ๋ก๊ทธ์ธ ์ธ์ ์ ์๋ฒ์์ ๊ด๋ฆฌํ๋ ค๋ฉด, ํธ๋ํฝ์ด ๋ง์์ง์๋ก ์๋ฒ ๋ถ๋ด์ด ์ปค์ง๊ณ , ๋ถํ ๋ถ์ฐ์ ์ํด ์ธ์ ๊ณต์ (Sticky Session) ๊ฐ์ ๊ฑธ ํด์ผ ํ๋๋ฐ ์ด๊ฒ ๊ฝค๋ ๊ท์ฐฎ์ต๋๋ค... ํ์ง๋ง JWT๋ ํด๋ผ์ด์ธํธ๊ฐ ์์ฒด์ ์ผ๋ก ์ธ์ฆ ์ ๋ณด๋ฅผ ๊ฐ๊ณ ์๊ธฐ ๋๋ฌธ์ ์๋ฒ์์๋ ์ด๊ฑธ ํ์ธ๋ง ํ๋ฉด ๋ฉ๋๋ค. ์ฆ, ํ์ฅ์ฑ(Scale-Out)์ ๊ฐํฉ๋๋ค.
2๏ธโฃ ๋น ๋ฆ
JWT๋ ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญ์ ๋ณด๋ผ ๋๋ง๋ค ํ์ํ ์ธ์ฆ ์ ๋ณด๋ฅผ ํฌํจํด์ ๋ณด๋ด๊ธฐ ๋๋ฌธ์, ์๋ฒ๊ฐ ๋ณ๋์ DB ์กฐํ ์์ด๋ ์ฌ์ฉ์์ ๊ถํ์ ๊ฒ์ฆํ ์ ์์ต๋๋ค. ์ฆ, ๋งค๋ฒ DB์ ์ ๊ทผํด์ ์ฌ์ฉ์์ ์ธ์ฆ ์ํ๋ฅผ ํ์ธํ ํ์๊ฐ ์์ผ๋ ์๋ต ์๋๊ฐ ๋นจ๋ผ์ง๋๋ค!
3๏ธโฃ ์ธ์ด์ ํ๋ซํผ์ ๊ด๊ณ์์ด ์ฌ์ฉ ๊ฐ๋ฅ
JWT๋ JSON ํฌ๋งท์ ๊ธฐ๋ฐ์ผ๋ก ํ๊ธฐ ๋๋ฌธ์ ์น๋ฟ๋ง ์๋๋ผ ๋ชจ๋ฐ์ผ ์ฑ, ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ ์ฒ, ์๋ฒ ๊ฐ ์ธ์ฆ ๋ฑ ๋ค์ํ ํ๊ฒฝ์์ ์ฝ๊ฒ ํ์ฉํ ์ ์์ต๋๋ค. Node.js, Python, Java, Go ๋ฑ ๋๋ถ๋ถ์ ์ธ์ด์์ ์ง์ํ๊ธฐ ๋๋ฌธ์ ํ๋ก ํธ์๋์ ๋ฐฑ์๋๊ฐ ์๋ก ๋ค๋ฅธ ๊ธฐ์ ์ ์จ๋ ๋ฌธ์ ์์ด ์ฐ๋ ๊ฐ๋ฅํฉ๋๋ค.
๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ , ํธํ๋ค๊ณ ๋ง๋ฅ ์ข์ ๊ฑด ์๋๋๊น! JWT๋ฅผ ์ธ ๋ ์กฐ์ฌํด์ผ ํ ์ ๋ ๋ง์ต๋๋ค.
JWT๋ ์ธ์ ์ ๋ณด๋ฅผ ์๋ฒ์ ์ ์ฅํ ํ์๊ฐ ์์ต๋๋ค.
JWT๋ ์๋ฒ ๊ฐ ๊ณต์ ๊ฐ ํ์ ์๋ ๋ฐฉ์์ด๊ธฐ ๋๋ฌธ์, ๋ง์ดํฌ๋ก์๋น์ค ํ๊ฒฝ์์๋ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
JWT๋ ์น๋ฟ๋ง ์๋๋ผ, ๋ชจ๋ฐ์ผ ์ฑ, ์๋ฒ ๊ฐ ์ธ์ฆ, API ์ธ์ฆ์๋ ํ์ฉ๋ฉ๋๋ค.
JWT๊ฐ ํธ๋ฆฌํ ๋งํผ, ๋ณด์์ ์ผ๋ก ์ ๊ฒฝ ์จ์ผ ํ ๋ถ๋ถ๋ ๋ง์ต๋๋ค. ๋์ถฉ ์ฌ์ฉํ๋ฉด ํฐ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์์ผ๋ ๋ฐ๋์ ํ์ธํด์ผ ํฉ๋๋ค.
1๏ธโฃ ํ ํฐ์ ๋์ฝ๋ฉํ ์ ์๋ค (์ํธํ ์๋!)
JWT๋ Base64๋ก ์ธ์ฝ๋ฉ๋์ด ์์ ๋ฟ, ์ํธํ๋ ๊ฒ ์๋๋๋ค. ์ฆ, ๋๊ตฌ๋ ์ง ํ ํฐ์ ๋์ฝ๋ฉํด์ ๋ด๋ถ ์ ๋ณด๋ฅผ ๋ณผ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
์ด๋ฐ ๋ฌธ์์ด์ Base64 ๋์ฝ๋ฉํ๋ฉด ๋ฐ๋ก ์๋ณธ JSON ๋ฐ์ดํฐ๊ฐ ๋์ต๋๋ค. ๊ทธ๋ฌ๋๊น ๋น๋ฐ๋ฒํธ ๊ฐ์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ์ ๋ JWT์ ๋ด์ง ๋ง์์ผ ํฉ๋๋ค.
2๏ธโฃ ๋ง๋ฃ ์๊ฐ์ ๋ฐ๋์ ์ค์ ํ์
JWT๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฒ์์ ๋ฐ๋ก ์ธ์
์ ๊ด๋ฆฌํ์ง ์๊ธฐ ๋๋ฌธ์, ํ ํฐ์ด ์ ์ถ๋๋ฉด ๋๊ตฌ๋ ํด๋น ํ ํฐ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋์ exp
(๋ง๋ฃ ์๊ฐ)๋ฅผ ์ค์ ํด์ ์ ํจ๊ธฐ๊ฐ์ ์งง๊ฒ ๋๋ ๊ฒ์ด ํ์์
๋๋ค! ์๋ฅผ ๋ค์ด, ๋ก๊ทธ์ธ ํ ํฐ์ 30๋ถ~1์๊ฐ ์ ๋๋ก ์ค์ ํ๊ณ , Refresh Token์ ๋ณ๋๋ก ๋ฐ๊ธํด์ ๊ด๋ฆฌํ๋ ๋ฐฉ์์ด ์ผ๋ฐ์ ์
๋๋ค.
3๏ธโฃ 'none' ์๊ณ ๋ฆฌ์ฆ์ ํ์ฉํ๋ฉด ์ ๋๋ค
JWT์ ํค๋ ๋ถ๋ถ์ ๋ณด๋ฉด alg
(์๊ณ ๋ฆฌ์ฆ) ๊ฐ์ด ์๋ค. ์ฌ๊ธฐ์ alg: "none"
์ผ๋ก ์ค์ ํ๋ฉด, ์๋ช
์ ๊ฒ์ฆํ์ง ์๊ณ ๊ทธ๋ฅ ํต๊ณผ์ํค๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ง์ฝ ์๋ฒ์์ ์ด๊ฑธ ํ์ฉํ๋ฉด, ๊ณต๊ฒฉ์๊ฐ ์๋ช
์ ์์ ์ ๊ฑฐํ ํ ํฐ์ ๋ง๋ค์ด์ ์๋ฒ๋ฅผ ์์ผ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋๊น ๋ฐ๋์ none
์๊ณ ๋ฆฌ์ฆ์ ํ์ฉํ์ง ์๋๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
4๏ธโฃ ํ ํฐ ์ ์ฅ ๋ฐฉ์ ์ฃผ์ (XSS, CSRF ๊ณต๊ฒฉ ๋๋น)
JWT๋ฅผ ํด๋ผ์ด์ธํธ์์ ์ ์ฅํ ๋, ๋ก์ปฌ ์คํ ๋ฆฌ์ง(localStorage)์ ์ ์ฅํ๋ฉด XSS(Cross-Site Scripting) ๊ณต๊ฒฉ์ ์ทจ์ฝํ ์ ์์ต๋๋ค. ๋์ , Secure, HttpOnly ์ฟ ํค๋ฅผ ์ฌ์ฉํ๋ฉด XSS ๊ณต๊ฒฉ์ ๋ง์ ์ ์์ต๋๋ค. ํ์ง๋ง ์ด ๊ฒฝ์ฐ CSRF(Cross-Site Request Forgery) ๊ณต๊ฒฉ์ ๋๋นํด์ผ ํ๋ฏ๋ก, CSRF ํ ํฐ์ ๊ฐ์ด ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
JWT๋ ๊ฐ๋ ฅํ ์ธ์ฆ ๋ฐฉ์์ด์ง๋ง, ์๋ชป ์ฌ์ฉํ๋ฉด ๋ณด์์ ์ฌ๊ฐํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ ์ฌํญ์ ๋ฐ๋์ ์ฃผ์ํด์ผ ํฉ๋๋ค.
JWT๋ Base64 ์ธ์ฝ๋ฉ์ด๊ธฐ ๋๋ฌธ์, ๋๊ตฌ๋ ๋์ฝ๋ฉํ ์ ์์ต๋๋ค.
base64 -d eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvbiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9
โก ๊ฒฐ๋ก : ๋น๋ฐ๋ฒํธ, ์นด๋ ๋ฒํธ, ๊ฐ์ธ์ ๋ณด ๊ฐ์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ์ ๋ ํฌํจํ์ง ๋ง์ธ์!
exp
(๋ง๋ฃ ์๊ฐ)๋ฅผ ์งง๊ฒ ์ค์ ํ๊ณ , ํ์ํ ๊ฒฝ์ฐ Refresh Token์ ํ์ฉํ์ฌ ์ฌ๋ฐ๊ธํ๋ ๋ฐฉ์์ด ์ข์ต๋๋ค.alg: "none"
์ค์ ์ ํ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.alg: "none"
์ ์ค์ ํ์ฌ ์๋ช
์์ด๋ ์ ํจํ JWT๋ก ์ธ์๋ ์ ์์ต๋๋ค.none
์๊ณ ๋ฆฌ์ฆ์ ํ์ฉํ์ง ์๋๋ก ์๋ฒ ์ค์ ์ ํ์ธํ์ธ์!JWT๋ ํ์คํ ํธ๋ฆฌํ ์ธ์ฆ ๋ฐฉ์์ด์ง๋ง, ๋ณด์์ ์ผ๋ก ์ ๊ฒฝ ์จ์ผ ํ ๋ถ๋ถ์ด ๋ง์ต๋๋ค.
๐ ์์ ํ๊ฒ JWT๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด?
JWT๋ ๊ฐ๋ ฅํ๊ณ ํ์ฅ์ฑ์ด ๋ฐ์ด๋ ์ธ์ฆ ๋ฐฉ์์ด์ง๋ง, ๋ณด์์ ์ผ๋ก ์ทจ์ฝํ ์ ์๋ ์์๋ค์ด ์์ต๋๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ์๋ ์์น์ ๊ผญ ์ง์ผ์ฃผ์ธ์! โ
โ ๋ฏผ๊ฐํ ์ ๋ณด๋ ์ ๋ ํฌํจํ์ง ๋ง ๊ฒ
โ ํ ํฐ์ ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ์ ์ฅํ์ง ์๊ณ , Secure HttpOnly Cookie๋ฅผ ์ฌ์ฉํ ๊ฒ
โ ์ ์ ํ ๋ง๋ฃ ์๊ฐ(exp)์ ์ค์ ํ๊ณ , Refresh Token์ ํ์ฉํ ๊ฒ
โ ์๋ฒ์์ none
์๊ณ ๋ฆฌ์ฆ์ ํ์ฉํ์ง ์๋๋ก ์ค์ ํ ๊ฒ
โ ๋น๋ฐ ํค(Secret Key)๋ฅผ ์์ ํ๊ฒ ๊ด๋ฆฌํ ๊ฒ
์ด์ JWT์ ๋ํด ๋ ๊น์ด ์ดํดํ๊ณ , ์ค๋ฌด์์ ์ฌ๋ฐ๋ฅด๊ฒ ์ ์ฉํด ๋ณด์ธ์! ๐
๋ค์์๋ CASA Tier2๋ฅผ ๋ฐ๊ธฐ ์ํ ์ธ์ฆ ๊ณผ์ ๋ ์ ๋ฆฌํด์ ์ฌ๋ ค๋ณด๊ฒ ๋ค. ์ค๋์ ์ฌ๊ธฐ๊น์ง ์ ๋ฆฌํฉ๋๋ค! ๐ ๋ค์์๋ CASA Tier2 ์ธ์ฆ ๊ณผ์ ๋ ์ ๋ฆฌํด๋ณผ ์์ ์ด๋ ๊ธฐ๋ํด ์ฃผ์ธ์!