๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Spring๐Ÿƒ

์Šคํ”„๋ง ์ˆ™๋ จ : Project MySelectShop (2)

728x90

์ถœ์ฒ˜ : ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„

 

๋ชฉํ‘œ

์ธ์ฆ/์ธ๊ฐ€์— ๋Œ€ํ•ด ์ดํ•ด

ํšŒ์›๊ฐ€์ž…/๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ์„ ๊ตฌํ˜„ํ•˜๊ณ  ํ๋ฆ„์„ ์ดํ•ด

ํ˜„ ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„ํ•œ ์ธ์ฆ/์ธ๊ฐ€ ๊ธฐ๋Šฅ์˜ ํ•œ๊ณ„๋ฅผ ์ดํ•ด

 

1. ์ธ์ฆ/ ์ธ๊ฐ€

์Šคํ”„๋ง์—์„œ ์ธ์ฆ/์ธ๊ฐ€๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ : ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ

์ธ์ฆ์ด๋ž€? ํ•ด๋‹น ์œ ์ €๊ฐ€ ์‹ค์ œ ์œ ์ €์ธ์ง€ ์ธ์ฆํ•˜๋Š” ๊ฒƒ

์ธ๊ฐ€๋ž€? ํ•ด๋‹น ์œ ์ €๊ฐ€ ํŠน์ • ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ์ง€ ํ—ˆ๊ฐ€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ

 

1) ์ธ์ฆ์˜ ๋ฐฉ์‹ : ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ธ์ฆ

-> ์ผ๋ฐ˜์ ์œผ๋กœ ์„œ๋ฒ„ - ํด๋ผ์ด์–ธํŠธ ๊ตฌ์กฐ, ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์—ฐ๊ฒฐ๋œ๋‹ค

-> Http ํ”„๋กœํ† ์ฝœ : ๋น„์—ฐ๊ฒฐ์„ฑ ๋ฌด์ƒํƒœ๋กœ ํ†ต์‹ 

๋น„์—ฐ๊ฒฐ์„ฑ : ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์Œ ~ ๋ฆฌ์†Œ์Šค ์ ˆ์•ฝ๋ชฉ์ 

๋ฌด์ƒํƒœ : ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š์Œ ~ ์š”์ฒญ์—๋งŒ ์‘๋‹ต, ๊ทธ ์„œ์‚ฌ๋Š” ์•Œ์ง€ ๋ชปํ•œ๋‹ค.

 

~ ์ฟ ํ‚ค - ์„ธ์…˜ ๋ฐฉ์‹ : ์„œ๋ฒ„๊ฐ€ ํŠน์ • ์œ ์ €๊ฐ€ ๋กœ๊ทธ์ธ๋˜์—ˆ๋‹ค๋Š” ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹

~ JWT ๊ธฐ๋ฐ˜ ์ธ์ฆ

JWT : ์ธ์ฆ์— ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์•”ํ˜ธํ™”์‹œํ‚จ ํ† ํฐ

 

*User API ์„ค๊ณ„

๊ธฐ๋Šฅ ๋ฉ”์„œ๋“œ URL ์š”์ฒญ ์‘๋‹ต
ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ GET /api/user/signup   signup.html
ํšŒ์›๊ฐ€์ž… POST /api/user/signup POST Form ํƒœ๊ทธ
{
"username" : String,
”password” : String,
”email : String,
”admin” : boolean,
”adminToken" : String
}
redirect:/api/user/login
๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ GET /api/user/login   login.html
๋กœ๊ทธ์ธ POST /api/user/login POST Form ํƒœ๊ทธ
{
"username" : String,
”password” : String
}
redirect:/api/shop

User ์—”ํ‹ฐํ‹ฐ

UserRoleEnum : ์—ญํ• ๋ณ„ ๊ถŒํ•œ ์„ค์ •

UserRepository ~JPARepository ์ƒ์†

SignupRequestDto : ํšŒ์›๊ฐ€์ž…์‹œ ์ž…๋ ฅํ•˜๋Š” ์ •๋ณด๋ฅผ ๋ฐ›๋Š” Dto

LoginRequestDto : ๋กœ๊ทธ์ธ ์‹œ ์ž…๋ ฅํ•˜๋Š” ์ •๋ณด๋ฅผ ๋ฐ›๋Š” Dto

 

ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ

UserController : ๋กœ๊ทธ์ธ/ ํšŒ์›๊ฐ€์ž…๊ธฐ๋Šฅ ์ถ”๊ฐ€ -> ๊ด€๋ฆฌ์ž ํ† ํฐ ์„ ์–ธ -> ํšŒ์›๊ฐ€์ž… ๋ฉ”์„œ๋“œ ์ž‘์„ฑ ~ ์ž‘์„ฑ์™„๋ฃŒ ์‹œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ฐ˜ํ™˜

UserService : ํšŒ์› ์ค‘๋ณตํ™•์ธ ๋ฐ ์‚ฌ์šฉ์ž ์—ญํ•  ํ™•์ธํ•˜๋Š” signup ๋ฉ”์„œ๋“œ ์ž‘์„ฑ ~ signupRequestDto์—์„œ ๋ฐ›์€ user ์ •๋ณด๋ฅผ UserRepository์— ์ €์žฅ

UserRepository : ์ด๋ฆ„์œผ๋กœ ์ค‘๋ณตํšŒ์›์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ Optional ํƒ€์ž… findByName(String username) ๋ฉ”์„œ๋“œ

 

๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ

UserController : UserRequestDto์—์„œ ์ •๋ณด๋ฅผ ๋ฐ›์•„ UserService login ๋ฉ”์„œ๋“œ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ. ๋กœ๊ทธ์ธ ์‹œ ๋ฉ”์ธํŽ˜์ด์ง€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ ์ž‘์„ฑ

Service : username ๋ฐ password๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ

 

2. JWT๋ฅผ ์ด์šฉํ•œ ์ธ์ฆ/์ธ๊ฐ€

๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ ํ† ํฐ ๋ฐœ๊ธ‰

๋กœ๊ทธ์•„์›ƒ

๋กœ๊ทธ์ธ ํ•œ ์œ ์ €๋งŒ ๊ด€์‹ฌ์ƒํ’ˆ ๋“ฑ๋ก, ์กฐํšŒ, ์ตœ์ €๊ฐ€ ๋“ฑ๋ก ๊ฐ€๋Šฅ

ADMIN ๊ณ„์ •์€ ๋ชจ๋“  ์ƒํ’ˆ ์กฐํšŒ ๊ฐ€๋Šฅ

 

~ ๋กœ๊ทธ์ธํ•œ ์œ ์ €๊ฐ€ ๋“ฑ๋กํ•œ ๊ด€์‹ฌ์ƒํ’ˆ๋งŒ ๋ณด์—ฌ์•ผํ•˜๋Š”๋ฐ ๋“ฑ๋กํ•œ ๋ชจ๋“  ๊ด€์‹ฌ์ƒํ’ˆ์ด ๋ณด์ด๋Š” ๋ฌธ์ œ : ๊ด€์‹ฌ์ƒํ’ˆ์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋งˆ๋‹ค ์‚ฌ์šฉ์ž ํ™•์ธ์„ ํ•œ๋‹ค๋ฉด ๋ณด์•ˆ์œ„ํ—˜ ๋…ธ์ถœ

 

Http ํ”„๋กœํ† ์ฝœ์€ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ฟ ํ‚ค์™€ ์„ธ์…˜์€ ์ด๋Ÿฐ ์ƒํƒœ๊ฐ€ ์ €์žฅ๋œ ์ƒํƒœ๋กœ ์žˆ์„ ์ˆ˜ ์žˆ๋„๋ก ์œ ์ง€์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•

์ฟ ํ‚ค : ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅ๋  ๋ชฉ์ ์œผ๋กœ ์ƒ์„ฑํ•œ ์ž‘์€ ์ •๋ณด๋ฅผ ๋‹ด์€ ํŒŒ์ผ

 

์„ธ์…˜ : ์„œ๋ฒ„์—์„œ ์ผ์ •์‹œ๊ฐ„๋™์•ˆ ํด๋ผ์ด์–ธํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ ๋ณ„๋กœ ์œ ์ผ๋ฌด์ดํ•œ '์„ธ์…˜ID'๋ฅผ ๋ถ€์—ฌํ•œ ํ›„ ํด๋ผ์ด์–ธํŠธ ๋ณ„ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์— ์ €์žฅ

์„œ๋ฒ„์—์„œ ์ƒ์„ฑํ•œ '์„ธ์…˜ID'๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์ฟ ํ‚ค๊ฐ’('์„ธ์…˜ ์ฟ ํ‚ค')์œผ๋กœ ์ €์žฅ๋˜์–ด ํด๋ผ์ด์–ธํŠธ ์‹๋ณ„์— ์‚ฌ์šฉ๋œ๋‹ค

  1. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— 1๋ฒˆ ์š”์ฒญ
  2. ์„œ๋ฒ„๊ฐ€ ์„ธ์…˜ID ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์‘๋‹ต ํ—ค๋”์— ์ „๋‹ฌ
    1. ์„ธ์…˜ ID ํ˜•ํƒœ: "SESSIONID = 12A345"
  3. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฟ ํ‚ค๋ฅผ ์ €์žฅ ('์„ธ์…˜์ฟ ํ‚ค')
  4. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— 2๋ฒˆ ์š”์ฒญ
    • ์ฟ ํ‚ค๊ฐ’ (์„ธ์…˜ ID) ํฌํ•จํ•˜์—ฌ ์š”์ฒญ
  5. ์„œ๋ฒ„๊ฐ€ ์„ธ์…˜ID ๋ฅผ ํ™•์ธํ•˜๊ณ , 1๋ฒˆ ์š”์ฒญ๊ณผ ๊ฐ™์€ ํด๋ผ์ด์–ธํŠธ์ž„์„ ์ธ์ง€
  ์ฟ ํ‚ค ์„ธ์…˜
์„ค๋ช… ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅ๋  ๋ชฉ์ ์œผ๋กœ ์ƒ์„ฑํ•œ ์ž‘์€ ์ •๋ณด๋ฅผ ๋‹ด์€ ํŒŒ์ผ ์„œ๋ฒ„์—์„œ ์ผ์ •์‹œ๊ฐ„ ๋™์•ˆ ํด๋ผ์ด์–ธํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
์ €์žฅ ์œ„์น˜ ํด๋ผ์ด์–ธํŠธ(์›น ๋ธŒ๋ผ์šฐ์ €) ์›น ์„œ๋ฒ„
์‚ฌ์šฉ ์˜ˆ ์‚ฌ์ดํŠธ ํŒ์—…์˜ '์˜ค๋Š˜ ๋‹ค์‹œ๋ณด์ง€ ์•Š๊ธฐ' ์ •๋ณด ์ €์žฅ ๋กœ๊ทธ์ธ ์ •๋ณด ์ €์žฅ
๋งŒ๋ฃŒ ์‹œ์  ์ฟ ํ‚ค๋ฅผ ์ €์žฅํ•  ๋•Œ ๋งŒ๋ฃŒ ์‹œ์  ์„ค์ • ๊ฐ€๋Šฅ
(๋ธŒ๋ผ์šฐ์ € ์ข…๋ฃŒ ํ›„์—๋„ ์œ ์ง€ ๊ฐ€๋Šฅ)
์กฐ๊ฑด ์ค‘ ํ•˜๋‚˜๋ฅผ ๋งŒ์กฑํ•  ๊ฒฝ์šฐ ๋งŒ๋ฃŒ
1. ๋ธŒ๋ผ์šฐ์ € ์ข…๋ฃŒ
2. ํด๋ผ์ด์–ธํŠธ ๋กœ๊ทธ์•„์›ƒ
3. ์„œ๋ฒ„๊ฐ€ ์„ค์ •ํ•œ ์œ ์ง€๊ธฐ๊ฐ„๊นŒ์ง€ ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ์˜ ์žฌ์š”์ฒญ์ด ์—†๋Š” ๊ฒฝ์šฐ
์šฉ๋Ÿ‰ ์ œํ•œ ๋ธŒ๋ผ์šฐ์ € ๋ณ„๋กœ ์ƒ์ด
(ํฌ๋กฌ) ๋„๋ฉ”์ธ ๋‹น 180๊ฐœ
(ํฌ๋กฌ) ์ฟ ํ‚ค ํ•˜๋‚˜๋‹น 4kb
๊ฐœ์ˆ˜ ์ œํ•œ ์—†์Œ
(์›น ์„œ๋ฒ„์˜ ์„ธ์…˜ ์ €์žฅ์†Œ ํฌ๊ธฐ๊นŒ์ง€ ์ €์žฅ)
๋ณด์•ˆ ์ทจ์•ฝ : ํด๋ผ์ด์–ธํŠธ ์ชฝ์—์„œ ์ฟ ํ‚ค ์ •๋ณด๋ฅผ ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝ, ์‚ญ์ œ ๋ฐ ๊ฐ€๋กœ์ฑ„๊ธฐ ๊ฐ€๋Šฅ ๋น„๊ต์  ์•ˆ์ „ : ์„œ๋ฒ„์— ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์—
์ƒ๋Œ€์ ์œผ๋กœ ์•ˆ์ „

 

JWT : Json ํฌ๋งท์„ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž์˜ ์†์„ฑ์„ ์ €์žฅํ•˜๋Š” ์›น ํ† ํฐ ~ ์ €์žฅ๋œ ์ฟ ํ‚ค

JWT๊ฐ€ ํ•„์š”ํ•œ ์ด์œ !

์„œ๋ฒ„๊ฐ€ 2๋Œ€ ์ด์ƒ์ธ ๊ฒฝ์šฐ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๋ฅผ ํ†ตํ•ด ์ ‘์†์ด ์ด๋ฃจ์–ด์ง€๋Š”๋ฐ, ์ฟ ํ‚ค๋ฅผ ํ†ตํ•ฉ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด ํ˜ผ์„ ์ด ์ƒ๊น€

 

ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

์„ธ์…˜์„ ํ•œ ๊ณณ์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ์ €์žฅ์†Œ ์ƒ์„ฑ
๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ JWT๋กœ ์ €์žฅํ•˜์—ฌ ๊ฐ–๊ณ  ์žˆ๋‹ค๊ฐ€ JWT๋ฅผ ํ†ตํ•ด ์ธ์ฆ/์ธ๊ฐ€
ํšŒ์› ์ •๋ณด๋ฅผ ์‹œํฌ๋ฆฟ ํ‚ค๋กœ ์•”ํ˜ธํ™” ํ•œ ํ›„ JWT ์œ„์กฐ๊ฒ€์ฆ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ธ์ฆ

  • JWT ์žฅ/๋‹จ์ 

์žฅ์ 

= ๋™์‹œ ์ ‘์†์ž๊ฐ€ ๋งŽ์„ ๋•Œ ์„œ๋ฒ„ ์ธก ๋ถ€ํ•˜ ๋‚ฎ์ถค

= Client, Sever ๊ฐ€ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์„ ์‚ฌ์šฉํ•  ๋•Œ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๋‹ค

์˜ˆ) ์นด์นด์˜ค OAuth2 ๋กœ๊ทธ์ธ ์‹œ JWT Token ์‚ฌ์šฉ

๋‹จ์ 

๊ตฌํ˜„์˜ ๋ณต์žก๋„ ์ฆ๊ฐ€

=J WT ์— ๋‹ด๋Š” ๋‚ด์šฉ์ด ์ปค์งˆ ์ˆ˜๋ก ๋„คํŠธ์›Œํฌ ๋น„์šฉ ์ฆ๊ฐ€ (ํด๋ผ์ด์–ธํŠธ → ์„œ๋ฒ„)

= ๊ธฐ ์ƒ์„ฑ๋œ JWT ๋ฅผ ์ผ๋ถ€๋งŒ ๋งŒ๋ฃŒ์‹œํ‚ฌ ๋ฐฉ๋ฒ•์ด ์—†์Œ

~ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ์„ค์ •๋œ ๊ธฐํ•œ์— ๋งŒ๋ฃŒ๋˜๋Š” ๋“ฑ์ด ์•„๋‹ˆ๋ฉด ๊ณ„์† ์œ ์ง€๋จ

= Secret key ์œ ์ถœ ์‹œ JWT ์กฐ์ž‘ ๊ฐ€๋Šฅ

 

JWT ํ๋ฆ„

1. ๋กœ๊ทธ์ธ ์„ฑ๊ณต ->

๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ Secret Key ํ†ตํ•ด JWT๋กœ ์•”ํ˜ธํ™” -> JWT๋ฅผ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „๋‹ฌ

**Authorization: BEARER** <JWT> <!-- ์‘๋‹ต Header์— ์•„๋ž˜ ํ˜•ํƒœ๋กœ JWT ์ „๋‹ฌ -->

ex)
**Authorization: BEARER** eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzcGFydGEiLCJVU0VSTkFNRSI6IuultO2DhOydtCIsIlVTRVJfUk9MRSI6IlJPTEVfVVNFUiIsIkVYUCI6MTYxODU1Mzg5OH0.9WTrWxCWx3YvaKZG14khp21fjkU1VjZV4e9VEf05Hok

-> ํด๋ผ์ด์–ธํŠธ์—์„œ JWT ์ €์žฅ(์ฟ ํ‚ค, ๋กœ์ปฌ ์ €์žฅ์†Œ ๋“ฑ)

 

2. ํด๋ผ์ด์–ธํŠธ์˜ JWT ์ธ์ฆ ->

JWT๋ฅผ API ์š”์ฒญ ์‹œ๋งˆ๋‹ค Header์— ํฌํ•จ ->

์„œ๋ฒ„ : ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ „๋‹ฌํ•œ JWT๋ฅผ Secret Key๋ฅผ ์‚ฌ์šฉํ•ด ์œ„์กฐ๊ฒ€์ฆ + ์œ ํšจ๊ธฐ๊ฐ„ ๊ฒ€์‚ฌ ->

๊ฒ€์ฆ ์„ฑ๊ณต์‹œ : JWT์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€ ํ™•์ธ

 

JWT ๊ตฌ์กฐ

์‰ฝ๊ฒŒ ํ‰๋ฌธ์œผ๋กœ ๋ณตํ˜ธํ™” ๊ฐ€๋Šฅ, Secret Key๊ฐ€ ์žˆ์–ด์•ผ๋งŒ ์ˆ˜์ •์ด ๊ฐ€๋Šฅ ~ JWT๋Š” ReadOnly ๋ฐ์ดํ„ฐ

 

JWT ๊ตฌํ˜„ ์‹ค์Šต

dependencies์— JWT depedency ์ถ”๊ฐ€

application.properties์— JWT ์‹œํฌ๋ฆฟ ํ‚ค ์ถ”๊ฐ€ ~ Base64๋กœ ์ธ์ฝ”๋”ฉํ•œ ๊ฐ’

 

ํ† ํฐ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๊ฐ’

		// Header KEY ๊ฐ’
		public static final String AUTHORIZATION_HEADER = "Authorization";
		// ์‚ฌ์šฉ์ž ๊ถŒํ•œ ๊ฐ’์˜ KEY
    public static final String AUTHORIZATION_KEY = "auth";
		// Token ์‹๋ณ„์ž ~ ํ† ํฐ ์•ž์— ๋ถ™์ธ๋‹ค
    private static final String BEARER_PREFIX = "Bearer ";
		// ํ† ํฐ ๋งŒ๋ฃŒ์‹œ๊ฐ„
    private static final long TOKEN_TIME = 60 * 60 * 1000L;

		@Value("${jwt.secret.key}")
    private String secretKey; // appelication.properties์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜จ๋‹ค
    private Key key; // token์„ ๋งŒ๋“ค ๋•Œ ๋„ฃ์–ด์ค„ ํ‚ค ๊ฐ’
    private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

    @PostConstruct // ๊ตฌ๊ธ€๋ง ํ•ด๋ณด๊ธฐ
    public void init() { // ๊ฐ์ฒด ์ƒ์„ฑ์‹œ ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜
        byte[] bytes = Base64.getDecoder().decode(secretKey); // ๋””์ฝ”๋”ฉํ•œ ๋ฐ”์ดํŠธ๋ฅผ ๋„ฃ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.
        key = Keys.hmacShaKeyFor(bytes);
    }
		// header ํ† ํฐ์„ ๊ฐ€์ ธ์˜ค๊ธฐ
    public String resolveToken(HttpServletRequest request) {
        String bearerToken = request.getHeader(AUTHORIZATION_HEADER);
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(BEARER_PREFIX)) {
            return bearerToken.substring(7); 
            // AUTHORIZATION.header๋ฅผ ๊ฐ€์ ธ์˜จ ๋’ค ํ† ํฐ๊ณผ ๊ด€๋ จ์—†๋Š” ์•ž 7์ž๋ฆฌ ๊ธ€์ž๋ฅผ ๋นผ๊ณ  ๋ฐ˜ํ™˜
        }
        return null;
    }
		// ํ† ํฐ ์ƒ์„ฑ
    public String createToken(String username, UserRoleEnum role) {
        Date date = new Date();

        return BEARER_PREFIX +
                Jwts.builder()
                .setSubject(username) // ๊ณต๊ฐ„, ๊ณต๊ฐ„ ๋ถ€๋ถ„์— ์ด๋ฆ„์„ ๋„ฃ๋Š”๋‹ค
                .claim(AUTHORIZATION_KEY, role) 
                // ์‚ฌ์šฉ์ž ๊ถŒํ•œ, ๊ถŒํ•œ์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋Š” Auth ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
                .setExpiration(new Date(date.getTime() + TOKEN_TIME))
                // ์œ ํšจ๊ธฐ๊ฐ„ ์„ค์ •, ์ง€๊ธˆ์œผ๋กœ๋ถ€ํ„ฐ ์–ธ์ œ๊นŒ์ง€
                .setIssuedAt(date)
                // ์–ธ์ œ ๋ฐœ๊ธ‰ํ–ˆ๋Š”์ง€
                .signWith(key, signatureAlgorithm)
                // Key ๊ฐ์ฒด์™€ ์–ด๋–ค ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์•”ํ˜ธํ™”ํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ ~ ์‹ค์Šต : HS256
                .compact();
                // String ํƒ€์ž…์˜ JWT ํ† ํฐ์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค.
    }
		// ํ† ํฐ ๊ฒ€์ฆ
    public boolean validateToken(String token) {
        try {
            Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
            return true;
        } catch (SecurityException | MalformedJwtException e) {
            log.info("Invalid JWT signature, ์œ ํšจํ•˜์ง€ ์•Š๋Š” JWT ์„œ๋ช… ์ž…๋‹ˆ๋‹ค.");
        } catch (ExpiredJwtException e) {
            log.info("Expired JWT token, ๋งŒ๋ฃŒ๋œ JWT token ์ž…๋‹ˆ๋‹ค.");
        } catch (UnsupportedJwtException e) {
            log.info("Unsupported JWT token, ์ง€์›๋˜์ง€ ์•Š๋Š” JWT ํ† ํฐ ์ž…๋‹ˆ๋‹ค.");
        } catch (IllegalArgumentException e) {
            log.info("JWT claims is empty, ์ž˜๋ชป๋œ JWT ํ† ํฐ ์ž…๋‹ˆ๋‹ค.");
        }
        return false;
    }
		// ํ† ํฐ์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
    public Claims getUserInfoFromToken(String token) {
        return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
    // ์ธ์ฆํ•œ ํ† ํฐ์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด body๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค
    // ์•ž์—์„œ ํ† ํฐ ๊ฒ€์ฆ์„ ํ–ˆ๊ธฐ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ try catch๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์€ ํ˜•ํƒœ
    }

 

JWT ์ ์šฉ

User API ์„ค๊ณ„ ๋ณ€๊ฒฝ

๊ธฐ๋Šฅ ๋ฉ”์„œ๋“œ URL ์š”์ฒญ ์‘๋‹ต
๋กœ๊ทธ์ธ POST api/user/login {
"username" : String,
”password” : String
}

ajaxํ˜•์‹์œผ๋กœ ๋ณด๋ƒ„
Header
Authorization : Bearer <JWT>

success

์ฟ ํ‚ค ์ €์žฅ๋˜๋Š” ๋ชจ์Šต ์‹ค์Šต

์ƒ์„ฑ๋œ JWT ๋””์ฝ”๋”ฉ ์‹ค์Šต

+ ์ฃผ์˜ : JWT Payload์— ๋น„๋ฐ€๋ฒˆํ˜ธ ๋“ฑ์˜ ์ •๋ณด๋Š” ๋„ฃ์œผ๋ฉด ์•ˆ๋œ๋‹ค. ~ JWT์€ ๋ˆ„๊ตฌ๋‚˜ ๋ณตํ˜ธํ™”ํ• ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—

 

JWT๋ฅผ ์‚ฌ์šฉํ•œ ๊ด€์‹ฌ์ƒํ’ˆ ์กฐํšŒํ•˜๊ธฐ

User์™€ Product ๊ฐ„ ์—ฐ๊ด€๊ด€๊ณ„ ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค

๊ด€์‹ฌ์ƒํ’ˆ ์กฐํšŒํ•  ๋•Œ ํ† ํฐ ๋ณด๋‚ด๊ธฐ

๊ด€์‹ฌ์ƒํ’ˆ ์ถ”๊ฐ€ํ•  ๋•Œ ํ† ํฐ ๋ณด๋‚ด๊ธฐ

๊ด€์‹ฌ์ƒํ’ˆ ์ตœ์ €๊ฐ€ ์ถ”๊ฐ€ํ•  ๋•Œ ํ† ํฐ ๋ณด๋‚ด๊ธฐ

728x90