ํฐ์คํ ๋ฆฌ ๋ทฐ
J
SON W
EB T
OKEN
JWT๋?
- ํ ํฐ ์์ฒด์ ์ ๋ณด๋ฅผ ๋ด๊ณ ์์
- ๋ฌด๊ฒ์ง ์๊ณ
- ๊ฐํธํ๊ณ
- ์ฝ๊ฒ ์ ์ฉ ๊ฐ๋ฅ
- Base64 URL Safe Encoding์ ์ด์ฉํด์ URL, Cooke, Header ๋ฑ์ ์ฌ์ฉ ๊ฐ๋ฅ
- ์ค์์ ์ธ์ฆ ์๋ฒ, ๋ฐ์ดํฐ ์คํ ์ด์ ๋ํ ์์กด์ฑ์ด ์์ด์ ์์คํ ์ํ ํ์ฅ์ ์ ๋ฆฌํจ
- → ๊ธฐ์กด์ ์ธ์ฆ ์ ๋ณด๋ฅผ ์ธ์ ์ ์ ์ฅํ๋ ๋ฐฉ์์ ํด๋น ์๋ฒ์์๋ง ํด๋น ์ธ์ฆ ์ ๋ณด๋ฅผ ์ฌ์ฉํ ์ ์์ด์ ๋ฐ๋ก ์ธ์ ์๋ฒ๋ฅผ ๋ฌ์ผํ์ง๋ง, ํ ํฐ์ ํด๋ผ์ด์ธํธ์ ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ ์ธ์ ์๋ฒ๊ฐ ํ์ ์์ด์ง.
JWT๋ ๋ค์๊ณผ ๊ฐ์ 3๊ฐ์ ๋ถ๋ถ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์
aaaaaa.bbbbbb.cccccc
// ์์์๋ถํฐ .์ ๊ธฐ์ค์ผ๋ก ๋ค์๊ณผ ๊ฐ์
// ํค๋(header).๋ด์ฉ(payload).์๋ช
(signature)
ํค๋(Header)
- Signature๋ฅผ ํด์ฑํ๊ธฐ ์ํ ์๊ณ ๋ฆฌ์ฆ ์ ๋ณด
const header = {
"typ": "JWT",
"alg": "HS256"
}
Header๋ ๋๊ฐ์ง ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์
typ
: ํ ํฐ์ ํ์
์ ์ง์ → JWT
alg
: ํด์ฑ ์๊ณ ๋ฆฌ์ฆ์ ์ง์
alg์ ๊ธฐ์ ํ ์๊ณ ๋ฆฌ์ฆ์ ํ ํฐ์ ๊ฒ์ฆํ ๋ signature
๋ถ๋ถ์์ ์ฌ์ฉ๋จ!
→ ์ํธํํด์ ์ธ ๊ฒ ๊ฐ์ ๋๋์ด ํํ!
์ ๋ณด(Payload)
- ์๋ฒ์ ํด๋ผ์ด์ธํธ๊ฐ ์ฃผ๊ณ ๋ฐ๋, ์์คํ ์์ ์ค์ ๋ก ์ฌ์ฉ๋ ์ ๋ณด์ ๋ํ ๋ด์ฉ๋ค์ ๋ด๊ณ ์์.
{
"sub" : "mokhs00",
"auth" : "ROLE_USER"
"exp" : 1480849147370
}
ํด๋ ์(claim)
Payload ๋ถ๋ถ์ ๋ด๋ ์ ๋ณด์ ํ ์กฐ๊ฐ์ ํด๋ ์
(claim)์ด๋ผ๊ณ ๋ถ๋ฆ
key / value ํ ์์ผ๋ก ์ด๋ฃจ์ด์ง
ํด๋ ์๋ ํฌ๊ฒ ์ธ ๋ถ๋ฅ๋ก ๋๋์ด์ง
- ๋ฑ๋ก๋(registered) ํด๋ ์
- ๊ณต๊ฐ(public) ํด๋ ์
- ๋น๊ณต๊ฐ(private) ํด๋ ์
1. ๋ฑ๋ก๋(registered) ํด๋ ์
- ๋ฑ๋ก๋ ํด๋ ์๋ค์ ์๋น์ค์์ ํ์ํ ์ ๋ณด๋ค์ด ์๋, ํ ํฐ์ ๋ํ ์ ๋ณด๋ค์ ๋ด๊ธฐ ์ํด์ ์ด๋ฆ์ด ์ด๋ฏธ ์ ํด์ ธ์๋ ํด๋ ์!
→ ๊ทธ๋ฅ ์คํ์ผ๋ก ๋๊ปด์ง. ์ด๋ฏธ ๋ฑ๋ก๋์ด ์๋ค๋ ์๋ฏธ์์ ๋ช ์นญ์ด registered์ธ๋ฏ
- ๋ฑ๋ก๋ ํด๋ ์์ ์ฌ์ฉ์ ๋ชจ๋ ์ ํ์ ์
→ ์ฐ๋ ์ ์ฐ๋ ์์ ๋ผ๋ ๋ง
๋ฑ๋ก๋ ํด๋ ์ ์ข ๋ฅ
๋ฐ์ค ์น ๊ฒ๋ค์ ์ค์ํ๋ค๊ณ ์๊ฐํจ.
iss
: ํ ํฐ ๋ฐ๊ธ์ (issuer)sub
: ํ ํฐ ์ ๋ชฉ (subject)aud
: ํ ํฐ ๋์์ (audience)exp
: ํ ํฐ ๋ง๋ฃ ์๊ฐ (expiration) ์๊ฐ์ NumericDate ํ์์ ๋์ด์์ด์ผ ํจ.
๋น์ฐํ ์ด์ผ๊ธฐ์ง๋ง, ์ธ์ ๋ ํ์ฌ ์๊ฐ๋ณด๋ค ์ดํ๋ก ์ค์ ํด์ผํจ.nbf
: Not Before์ ์๋ฏธ, ํ ํฐ์ ํ์ฑ ๋ ์ง์ ๋น์ทํ ๊ฐ๋ .exp
์ ๋์ผํ๊ฒ NumericDate ํ์์ผ๋ก ๋ ์ง๋ฅผ ์ง์ . ํด๋น ๋ ์ง๊ฐ ์ง๋๊ธฐ ์ ๊น์ง ํ ํฐ์ด ์ฒ๋ฆฌ๋์ง ์์iat
: ํ ํฐ์ด ๋ฐ๊ธ๋ ์๊ฐ (issued at). ์ด ๊ฐ์ ์ฌ์ฉํ์ฌ ํ ํฐ์age
๊ฐ ์ผ๋ง๋ ๋์๋์ง ํ๋จํ ์ ์์.jti
:JWT์ ๊ณ ์ ์๋ณ์, ์ฃผ๋ก ์ค๋ณต์ ์ธ ์ฒ๋ฆฌ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด์ ์ฌ์ฉ๋จ. ์ผํ์ฉ ํ ํฐ์ ์ฌ์ฉํ๋ฉด ์ ์ฉํจ!
2. ๊ณต๊ฐ(public) ํด๋ ์
๊ณต๊ฐ ํด๋ ์๋ค์ ์ถฉ๋์ด ๋ฐฉ์ง๋ (collision-resistant) ์ด๋ฆ์ ๊ฐ์ง๊ณ ์์ด์ผํจ.
์ถฉ๋์ ๋ฐฉ์งํ๊ธฐ ์ํด์, ํด๋ ์ ์ด๋ฆ์ URI ํ์์ผ๋ก ์ง์
{
"https://www.naver.com/jwt_claims/is_admin" : true
}
3. ๋น๊ณต๊ฐ(private) ํด๋ ์
ํ ํฐ์ ์ฌ์ฉํ๋ ์ ์ธก๊ฐ(ํด๋ผ์ด์ธํธ <-> ์๋ฒ) ํ์ ํ์ ์ฌ์ฉ๋๋ ํด๋ ์ ์ด๋ฆ๋ค
์ด๋ฆ์ด ์ค๋ณต๋์ด ์ถฉ๋์ด ์๊ธธ ์ ์์ผ๋ ์ฃผ์
{
"username" : "mokhs00"
}
ex) PayLoad
{
"iss" : "mokhs.com",
"exp" : "1623857327070",
"userId" : "5190",
"username" : "mokhs"
}
โ์ฃผ์ - Base64 encoding์ padding ๋ฌธ์์ url-safe
base64
์ธ์ฝ๋ฉ ์์ =
๋ฌธ์๊ฐ ํ ๋๊ฐ ๋ถ์ ์ ์์.
์ด๋ base64
์ธ์ฝ๋ฉ์ padding
๋ฌธ์๋ผ๊ณ ๋ถ๋ฆผ
๊ทธ๋ฐ๋ฐ =
์ ํ๋ผ๋ฏธํฐ๋ก ์ธ์๋ ์ ์๊ธฐ์ url-safeํ์ง ์์
๋ฐ๋ผ์ ํจ๋ฉ ๋ฌธ์๋ฅผ ๋ชจ๋ ์ง์์ค์ผํจ!
- ํจ๋ฐ ๋ฌธ์๋ฅผ ์ ๊ฑฐํด๋ decoding ์ ์ ํ ๋ฌธ์ ๊ฐ ๋์ง ์์
์๋ช (Signature)
- JWT์ ๋ง์ง๋ง ๋ถ๋ถ!
- ํ ํฐ์ ์ ํจ์ฑ ๊ฒ์ฆ์ ์ํ ๋ฌธ์์ด
- ์ด ๋ฌธ์์ด์ ํตํด ์๋ฒ์์ ์ด ํ ํฐ์ด ์ ํจํ ํ ํฐ์ธ์ง ๊ฒ์ฆ ๊ฐ๋ฅ
- ํค๋(header)์ ์ธ์ฝ๋ฉ๊ฐ, ์ ๋ณด(payload)์ ์ธ์ฝ๋ฉ๊ฐ์ ํฉ์น ํ ์ฃผ์ด์ง ๋น๋ฐํค๋ก ํด์ฑ(hash)ํ์ฌ ์์ฑ
- ์๋ช ๋ถ๋ถ์ ๋ง๋๋ ์๋์ฝ๋(pseudocode)๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
- ๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ๋ง๋ hash๋ฅผ base64์ธ์ฝ๋ฉ์ ํ๋ฉด ๋ง์ง๋ง signature๋ถ๋ถ์ด ์์ฑ๋จ!
- ์ฌ๊ธฐ์ ํต์ฌ์ secret์ ์๋ฒ์ ๊ณ ์ ํ secret ๊ฐ์ ๋๋ฉด ํด๋น ์๋ฒ๋ง ์ธ์ฆ์ด ๊ฐ๋ฅํจ
- secret์ด ์๊ธฐ์ ํ ํฐ์ ์๋ณ์กฐ๋ฅผ ๋ง์ ์ ์์
- ๋ง์ฝ ํ ํฐ ๋ด์ฉ์ด ์๋ณ์กฐ๋์ด๋ secret์ ๋ฃ๊ณ hashํ์ ๋ ๊ธฐ์กด ์๋ช (signature)์ ์ผ์นํ์ง ์์ผ๋ฉด, ์๋ฒ์์ ์ธ์ฆ ๊ฑฐ๋ถ๋ฅผ ํ๋ฉด ๋จ!
header.payload.signature ํฉ์น๊ธฐ
- ๊ฐ ๋ถ๋ถ์ ์ค๊ฐ ๋ถ๋ถ์ ๋ฌธ์์ด "."์ ๋ถ์ฌ์ ํฉ์น๋ฉด ํ ํฐ ์์ฑ!
๋ง๋ฌด๋ฆฌ
JWT ์ฅ์
- ์ค์์ ์ธ์ฆ ์๋ฒ, ๋ฐ์ดํฐ ์คํ ์ด์ ๋ํ ์์กด์ฑ์ด ์์.
→ ์์คํ ์ํ ํ์ฅ์ ์ ๋ฆฌ
- Base64 URL Safe Encoding ์ฌ์ฉ
→ URL, Cooke, Header ๋ชจ๋ ์ฌ์ฉ ๊ฐ๋ฅ
- { token : "header.payload.signature" }
JWT ๋จ์
- Payload์ ์ ๋ณด๊ฐ ๋ง์์ง๋ฉด ๋คํธ์ํฌ ์ฌ์ฉ๋ ์ฆ๊ฐ, ๋ฐ์ดํฐ ์ค๊ณ ๊ณ ๋ ค ํ์
- ํ ํฐ์ด ํด๋ผ์ด์ธํธ์ ์ ์ฅ๋จ, ์๋ฒ์์ ํด๋ผ์ด์ธํธ์ ํ ํฐ์ ์กฐ์ํ ์ ์์.
์ฐธ๊ณ
'BackEnd' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์์ฆ ๋ ์ค๋ฅด๋ gRPC ํบ์๋ณด๊ธฐ (2) | 2022.12.04 |
---|---|
Nginx 403 (13 Permission denied) ํด๊ฒฐํ๊ธฐ (0) | 2021.10.30 |
์ข์ ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ 5๊ฐ์ง ์์น(SOLID) (0) | 2021.06.12 |
HTTP ๋ฉ์๋ (0) | 2021.05.28 |
HTTP ์ํ์ฝ๋ (0) | 2021.05.22 |
- Total
- Today
- Yesterday
- rate limit
- 2๋ ์ฐจ ์๋ฒ ๊ฐ๋ฐ์
- ์ข์ ์ฝ๋๋ ๋ฌด์์ธ๊ฐ?
- Go
- Golang
- HTTP
- Aws Reinvent 2023
- golang oomkilled
- ํ(Heap)
- mysql ์คํ ๊ณํ
- 2023 ๊ฐ๋ฐ์ ํ๊ณ
- ๋ฐฑ์ค
- ์๊ณ ๋ฆฌ์ฆ
- ํ๋ก๊ทธ๋๋จธ์ค
- ์ฅ์ ํ๊ณ
- AWS re:Invent 2023
- ๋ฑ ํฌ์๋ฌ๋ ๊ฐ๋ฐ์
- kotlin s3 upload
- ๊น์ด/๋๋น ์ฐ์ ํ์(DFS/BFS)
- grpc client
- ํธ๋์ญ์ ๊ฒฉ๋ฆฌ ์์ค
- ํด์
- ์ฝ๋ฉํ ์คํธ
- ์คํ/ํ
- 2023 ํ๊ณ
- ์ข์ ๊ฐ๋ฐ์ ๋๊ธฐ
- mysql
- ์ข์ ๊ฐ๋ฐ์
- ์ถ์ ์ง๋
- ์ข์ ์์ง๋์ด
์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |