JWT
๐ JWT๋?
JSON Web Token(JWT)
๋ ๋ ๊ฐ์ฒด ๊ฐ JSON ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ์์ ํ๊ฒ ์ ๋ณด๋ฅผ ์ ์กํ๊ธฐ ์ํ ํ์ค์ด๋ค.
โ์ธ์ฆโ ๊ณผ์ ์์ JWT๋ฅผ ์ฌ์ฉํ๋ค. ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ๋ฉด, ์๋ฒ๋ ์ฌ์ฉ์์ ์ ๋ณด์ ๊ถํ์ ๋ด์ JWT๋ฅผ ๋ฐ๊ธํ๋ค. ์ดํ ์ฌ์ฉ์๋ JWT๋ฅผ ํตํด ์์ ์ ์ฆ๋ช ํ๊ณ , ์๋ฒ๋ JWT์ ์ ํจ์ฑ๋ง ๊ฒ์ฆํ๋ฉด ๋๋ค.
๐ ๊ตฌ์กฐ
JWT๋ โ.โ์ผ๋ก ๊ตฌ๋ถ๋ ์ธ ๋ถ๋ถ์ผ๋ก ๊ตฌ์ฑ๋๋ฉฐ, ๊ฐ ๋ถ๋ถ์ Base64URL
๋ก ์ธ์ฝ๋ฉ๋์ด ์๋ค.
Header
1
2
3
4
{
"alg": "HS256", // ์๋ช
์๊ณ ๋ฆฌ์ฆ
"typ": "JWT" // ํ ํฐ ํ์
}
ํค๋์๋ ํ ํฐ์ ์ข ๋ฅ์ ์๋ช ์ ์ฌ์ฉ๋ ์๊ณ ๋ฆฌ์ฆ ์ ๋ณด๋ฅผ ๋ด๋๋ค.
Payload
1
2
3
4
5
6
{
"sub": "user123",
"username": "senior.dev",
"role": "ADMIN",
"exp": 1672531199
}
ํ์ด๋ก๋์๋ ํ ํฐ์ ๋ด์ ์ค์ ์ ๋ณด์ธ claim
์ ํฌํจํ๋ค. ํด๋ ์์ด๋ ํ์ด๋ก๋์ ๋ด๋ ๊ฐ ์ ๋ณด๋ฅผ ๋งํ๋ค.
ํด๋ ์์๋ ํฌ๊ฒ ์ธ ๊ฐ์ง ์ข ๋ฅ๊ฐ ์กด์ฌํ๋ค.
Registered Claim
์ ํ์ค์ผ๋ก ์ ์๋ ํด๋ ์์ด๋ค. ํ์๋ ์๋๋ฉฐ, ์ ํ์ ์ผ๋ก ์์ฑํ๋ฉด ๋๋ค.
ํด๋ ์ | ์ค๋ช |
---|---|
iss | ํ ํฐ ๋ฐ๊ธ์ |
sub | ํ ํฐ์ ์ฃผ์ฒด |
aud | ํ ํฐ ์์ ์ |
exp | ํ ํฐ ๋ง๋ฃ ์๊ฐ |
iat | ํ ํฐ ๋ฐ๊ธ ์๊ฐ |
Public Claim
์ ์ถฉ๋์ ๋ฐฉ์งํ๊ธฐ ์ํด URI ํ์์ผ๋ก ์ด๋ฆ์ ์ง๋ ํด๋ ์์ด๋ค.
Private Claim
์ ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ ํ์ํ์ฌ ์ฌ์ฉํ๋ ํด๋ ์์ด๋ค.
ํ์ด๋ก๋๋ Base64URL๋ก ์ธ์ฝ๋ฉ๋ ๋ฟ, ์ํธํ๋ ๊ฒ์ด ์๋๋ค. ๋ฐ๋ผ์ ๋๊ตฌ๋ ๋์ฝ๋ฉํ์ฌ ๋ณผ ์ ์์ผ๋ฏ๋ก ๋น๋ฐ๋ฒํธ์ ๊ฐ์ ๋ฏผ๊ฐ ์ ๋ณด๋ ๋ด์ผ๋ฉด ์ ๋๋ค.
signature
์๋ช ์ ํตํด ํ ํฐ์ ์์กฐ ์ฌ๋ถ, ๋ฐ๊ธ์๊ฐ ์ ๋ขฐ ๊ฐ๋ฅํ์ง ํ์ธํ ์ ์๋ค. ํ ํฐ์ ๋ฌด๊ฒฐ์ฑ๊ณผ ์ธ์ฆ์ ๋ณด์ฅํ๋ค.
ํค๋์ ํ์ด๋ก๋๋ Base64URL๋ก ์ธ์ฝ๋ฉํ ํ, ๋ ๋ฌธ์์ด์ โ.โ์ผ๋ก ์ฐ๊ฒฐํ๋ค. ์ฐ๊ฒฐ๋ ๋ฌธ์์ด์ ํค๋์ ๋ช
์๋ ์๊ณ ๋ฆฌ์ฆ(alg
)์ ์๋ฒ์ ๋น๋ฐ ํค๋ฅผ ํตํด ์ํธํํ๋ค. ์ด๋ ๊ฒ ๊ตฌํ ๊ฐ์ด ์๋ช
์ด ๋๋ค.
๐ ๋์ ๊ณผ์
- ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ์์ฒญ์ ๋ณด๋ธ๋ค.
- ์๋ฒ๋ ์ฌ์ฉ์์ ์๊ฒฉ ์ฆ๋ช ์ ํ์ธํ๊ณ , ์ฑ๊ณต ์ ํ์ํ ํด๋ ์์ ๋ด์ JWT๋ฅผ ์์ฑํ์ฌ ์๋ช ํ๋ค.
- ์์ฑ๋ JWT๋ฅผ ํด๋ผ์ด์ธํธ์ ์ ๋ฌํ๋ค.
- ํด๋ผ์ด์ธํธ๋ JWT๋ฅผ ์์ ํ ๊ณณ์ ์ ์ฅํ๋ค.
- ํด๋ผ์ด์ธํธ๋ ๋ณดํธ๋ API์ ์ ๊ทผํ ๋๋ง๋ค HTTP
Authorization
ํค๋์Bearer
์คํด๊ณผ ํจ๊ป JWT๋ฅผ ๋ด์ ๋ณด๋ธ๋ค. - ์๋ฒ๋ ํค๋์์ JWT๋ฅผ ์ถ์ถํ์ฌ ๊ฒ์ฆํ๋ค.
- ๊ฒ์ฆ์ ํต๊ณผํ๋ฉด JWT์ ํ์ด๋ก๋์ ๋ด๊ธด ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์ ๋ขฐํ๊ณ ์์ฒญ์ ์ฒ๋ฆฌํ๋ค.
๐ ์ฅ๋จ์
๊ฐ์ฅ ํฐ ์ฅ์ ์ ์๋ฒ๊ฐ ์ํ๋ฅผ ๊ด๋ฆฌํ์ง ์๊ฒ ๋๋ฏ๋ก ์ํ์ ํ์ฅ์ ์ ๋ฆฌํด์ง๋ค. ๋ถํ์ํ DB ์กฐํ๋ฅผ ์ค์ผ ์ ์์ผ๋ฉฐ, ๋ค์ํ ๋๋ฉ์ธ ๊ฐ ์์ ํ๊ฒ ์ ๋ณด๋ฅผ ๊ตํํ ์ ์๋ค.
๊ทธ๋ฌ๋ JWT๋ ์ ํจ๊ธฐ๊ฐ ๋์ ์ ํจํ๋ฉฐ, ๋ง์ฝ ํ์ทจ๋๋ฉด ๋ง๋ฃ๋ ๋๊น์ง ๊ณต๊ฒฉ์๊ฐ ์ฌ์ฉํ ์ ์๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ฒ ์ํด Access Token์ ์ ํจ๊ธฐ๊ฐ์ ์งง๊ฒ ์ค์ ํ๊ณ Refresh Token์ผ๋ก ์ฃผ๊ธฐ์ ์ผ๋ก ํ ํฐ์ ์ฌ๋ฐ๊ธํ๋๋ก ๊ตฌํํ๋ค.
๋ํ ๋ก๊ทธ์์ ๋ฑ์ ํ๊ฒ ๋๋ฉด ๋ฐ๊ธ๋ ํ ํฐ์ ๋ฌดํจํํด์ผ ํ๋๋ฐ, JWT๋ stateless์ด๋ฏ๋ก ์๋ฒ์์ ํ ํฐ์ ๊ฐ์ ๋ก ๋ฌดํจํํ๊ธฐ๋ ์ด๋ ต๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ณ๋์ Blacklist๋ฅผ ๊ตฌํํ์ฌ ๋ก๊ทธ์์๋ ํ ํฐ์ Redis ๋ฑ์ ์ ์ฅํ์ฌ ํ์ธํ๋๋ก ๊ตฌํํ๋ค.
๐ ์ฐธ๊ณ
https://ivory-room.tistory.com/88