๊ฐœ๋ฐœ์ž HOON
๐Ÿ› HOON DEVLog
๊ฐœ๋ฐœ์ž HOON
์ „์ฒด ๋ฐฉ๋ฌธ์ž
์˜ค๋Š˜
์–ด์ œ
  • ๐Ÿ˜Ž ์ „์ฒด ์นดํ…Œ๊ณ ๋ฆฌ (137)
    • ๐Ÿ“ ์‹ ์ž… ์ธํ„ฐ๋ทฐ ์ค€๋น„ (7)
    • ๐Ÿฆ” ์ทจ์—…์ค€๋น„ ๊ธฐ๋ก (7)
    • โ˜• ์ž๋ฐ” : JAVA (5)
    • ๐Ÿ ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ๋Œ€๋น„ : PS (80)
    • ๐ŸŒฑ ๋ฐฑ์—”๋“œ : Backend (13)
    • ๐Ÿงช ์ปดํ“จํ„ฐ๊ณผํ•™ : CS (11)
    • ๐Ÿ—‚ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค : DB (1)
    • ๐Ÿƒ‍โ™‚๏ธ DEVLOG (8)
    • โš™๏ธ Trouble Shooting (5)

๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

  • ํ™ˆ
  • GitHub
  • Resume

๊ณต์ง€์‚ฌํ•ญ

์ธ๊ธฐ ๊ธ€

์ตœ๊ทผ ๊ธ€

ํ‹ฐ์Šคํ† ๋ฆฌ

hELLO ยท Designed By ์ •์ƒ์šฐ.
๊ฐœ๋ฐœ์ž HOON

๐Ÿ› HOON DEVLog

[Spring] Spring Security + OAuth2.0 + JWT Token์„ ํ™œ์šฉํ•œ ์†Œ์…œ๋กœ๊ทธ์ธ ์ด์ •๋ฆฌ - (1) ๋ฐฐ๊ฒฝ ์ง€์‹ ์ดํ•ดํ•˜๊ธฐ, ์ „์ฒด ๊ทธ๋ฆผ ์‚ดํŽด๋ณด๊ธฐ
๐ŸŒฑ ๋ฐฑ์—”๋“œ : Backend

[Spring] Spring Security + OAuth2.0 + JWT Token์„ ํ™œ์šฉํ•œ ์†Œ์…œ๋กœ๊ทธ์ธ ์ด์ •๋ฆฌ - (1) ๋ฐฐ๊ฒฝ ์ง€์‹ ์ดํ•ดํ•˜๊ธฐ, ์ „์ฒด ๊ทธ๋ฆผ ์‚ดํŽด๋ณด๊ธฐ

2023. 9. 22. 16:37

 

 

 

 

 

๐Ÿ™‹๐Ÿป ์„œ๋ก 

NEO ํ† ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์†Œ์…œ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ธํ„ฐ๋„ท ์ƒ์˜ ๋งŽ์€ ๊ธ€์„ ์ฝ๊ณ , ๋„์›€์„ ๋งŽ์ด ๋ฐ›์•˜์œผ๋‚˜ ์ •๋ณด๊ฐ€ ํ•œ๋ฐ ๋ชจ์—ฌ์žˆ์ง€ ์•Š๊ณ  ๋ณธ์ธ์ด ๊ฐœ์ธ์ ์œผ๋กœ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š๋Š” ๋ถ€๋ถ„์ด ๋งŽ์•„ ๋‚˜์ค‘์— ๋‹ค์‹œ ๊ตฌํ˜„ํ•  ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•ด ๊ธ€๋กœ ์ž‘์„ฑํ•˜๊ธฐ๋กœ ๋งˆ์Œ์„ ๋จน์—ˆ์Šต๋‹ˆ๋‹ค.

 

๋ถ€์กฑํ•œ ๋‚ด์šฉ์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ๋” ์ข‹์€ ๋‚ด์šฉ์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ๋‹ฌ์•„์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ข‹์€ ํ”ผ๋“œ๋ฐฑ์€ ์–ธ์ œ๋‚˜ ํ™˜์˜์ด๋ฉฐ, ์ œ ๊ธ€์ด ์†Œ์…œ๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•˜๋ ค๋Š” ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ์ข‹์€ ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ํ•ฉ๋‹ˆ๋‹ค.

 

๊ธ€์˜ ์ง„ํ–‰์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์ด์–ด์งˆ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

1. ๋ฐฐ๊ฒฝ์ง€์‹ ์ดํ•ดํ•˜๊ธฐ, ์ „์ฒด ๊ทธ๋ฆผ ์‚ดํŽด๋ณด๊ธฐ (OAuth2, JWT Token, ํ”„๋กœ์ ํŠธ ์ „์ฒด ๋„์‹ํ™”)
2. Naver, Kakao, Google์— ํ”„๋กœ์ ํŠธ๋ฅผ OAuth2 Client๋กœ ์„ค์ •ํ•˜๊ธฐ
3. Spring OAuth2.0 Client๋ฅผ ํ™œ์šฉํ•œ OAuth2.0 ํด๋ผ์ด์–ธํŠธ ๋ฐฑ์—”๋“œ ๊ตฌํ˜„
4. Redis์™€ JWT ํ† ํฐ์„ ์‚ฌ์šฉํ•œ ์šฐ๋ฆฌ ์„œ๋น„์Šค์— ๋Œ€ํ•œ ์ธ์ฆ๊ณผ ์ธ๊ฐ€์™€ ๊ตฌํ˜„
5. OAuth2.0๊ณผ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ, Spring REST Docs ์ž‘์„ฑ

 

 

๐Ÿ’œ NEO ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ ์„ค๋ช…

์†Œ์…œ ๋กœ๊ทธ์ธ ์ ์šฉ๊ณผ ์ธ์ฆ ๋ฐ ์ธ๊ฐ€ ์ ์šฉ ๋ฐฉ์‹์€ ํ”„๋กœ์ ํŠธ ๋ณ„๋กœ ์ฒœ์ฐจ๋งŒ๋ณ„์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์•ž์œผ๋กœ์˜ ๋‚ด์šฉ์— ์žˆ์–ด์„œ ์ฐจ์ด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ์—, ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•˜๊ณ  ๋น„์Šทํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด ์ œ๊ฐ€ ์ ์šฉํ•œ ๋‚ด์šฉ์„ ์ฐธ๊ณ ๋กœ ์—ฌ๊ฒจ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

- NEO๋Š” ์›น์ด ์•„๋‹Œ, iOS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค.
- ๋ฐฑ์—”๋“œ๋ฅผ ๋ณ„๋„๋กœ ๋‘๊ณ  ์žˆ์œผ๋ฉฐ, ๋ฐฑ์—”๋“œ๋ฅผ ํ†ตํ•ด OAuth2 ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค (๋ฐฑ์—”๋“œ๊ฐ€ OAuth2.0 Client)
- OAuth2 ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์–ป๊ณ  1์ฐจ ํšŒ์›๊ฐ€์ž…์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค
- ์ถ”ํ›„์— ์‚ฌ์šฉ์ž ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ž…๋ ฅ ๋ฐ›์•„ 1์ฐจ ํšŒ์›๊ฐ€์ž…๋œ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•ด ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค.
- ๋กœ๊ทธ์ธ ๋œ ์‚ฌ์šฉ์ž์—๊ฒŒ OAuth2 AccessToken์„ ์ง์ ‘ ์ฃผ์ง€ ์•Š๊ณ , ๋ฐฑ์—”๋“œ์—์„œ ์ž์ฒด์ ์œผ๋กœ ๋ฐœ๊ธ‰ํ•˜๋Š” JWT Token์„ ์ง€๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.
- JWT Token์€ Access Token๊ณผ Refresh Token์œผ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

 

 

๐Ÿ ํ”„๋กœ์ ํŠธ ํ™˜๊ฒฝ

NEO์—์„œ ์‚ฌ์šฉ๋œ dependency์ž…๋‹ˆ๋‹ค. ํ™˜๊ฒฝ์— ์žˆ์–ด์„œ ์ฃผ์˜ํ•  ์ ์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

- NEO์—์„œ ์‚ฌ์šฉํ•œ JWT ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š”, auth0:java-jwt ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ io:jsonwebtoken:jjwt ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘ auth0:java-jwt๋ฅผ ์„ ํƒ

- Spring Security 6.1.2 ๋ฒ„์ „์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ธํ„ฐ๋„ท ์ƒ์˜ ๋Œ€๋‹ค์ˆ˜์˜ ์ž๋ฃŒ(๊ตฌ๋ฒ„์ „)์— ๋น„ํ•ด Security Config ํŒŒํŠธ์—์„œ ๋‹ค๋ฅธ ์ฝ”๋“œ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. (๋น„๊ต์  ์ตœ์‹ ๋ฒ„์ „์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด์ „์— ์‚ฌ์šฉ๋˜๋˜ method๊ฐ€ ๋Œ€๋ถ€๋ถ„ deprecated, ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋งž๋Š” ๋ฉ”์†Œ๋“œ๋กœ ๋Œ€๋ถ€๋ถ„ ๋ฐ”๋€œ.)

- Java 17
- SpringBoot 3.1.2
- 'com.auth0:java-jwt:4.2.1'
- 'spring-boot-starter-data-redis:3.1.2'
- 'spring-boot-starter-security:3.1.2' (spring-security-web, spring-security-config:6.1.2)
- 'spring-boot-starter-oauth2-client:3.1.2' (spring-security-oauth2-client, oauth2-jose:6.1.2)

 

 

๐Ÿ˜Ž OAuth2.0

โœ… OAuth2.0์ด๋ž€?

 

'OAuth(Open Authorization)'๋Š” ์ธํ„ฐ๋„ท ์‚ฌ์šฉ์ž๋“ค์ด ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ , ๋‹ค๋ฅธ ์›น์‚ฌ์ดํŠธ ์ƒ์˜ ์ž์‹ ๋“ค์˜ ์ •๋ณด์— ๋Œ€ํ•ด ์›น์‚ฌ์ดํŠธ๋‚˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ณตํ†ต์ ์ธ ์ˆ˜๋‹จ์œผ๋กœ์จ ์‚ฌ์šฉ๋˜๋Š”, ์ ‘๊ทผ ์œ„์ž„์„ ์œ„ํ•œ ๊ฐœ๋ฐฉํ˜• ํ‘œ์ค€์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

์‚ฌ์šฉ์ž์˜ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ ์—†์ด ์ ‘๊ทผ ๊ถŒํ•œ์„ ์œ„์ž„๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์€, ๋กœ๊ทธ์ธ ๋ฐ ๊ฐœ์ธ์ •๋ณด ๊ด€๋ฆฌ ์ฑ…์ž„์„ 'Third-Party Application(google, kakao, naver ๋“ฑ)'์— ์œ„์ž„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์œผ๋กœ, ๋กœ๊ทธ์ธ ๋ฐ ๊ฐœ์ธ์ •๋ณด ๊ด€๋ฆฌ์— ๋Œ€ํ•œ ์ฑ…์ž„์„ ์œ„์ž„ํ•˜๋Š” ๊ฒƒ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ถ€์—ฌ๋ฐ›์€ ์ ‘๊ทผ ๊ถŒํ•œ์„ ํ†ตํ•ด ์„œ๋“œํŒŒํ‹ฐ ํ”„๋กœ๋ฐ”์ด๋”๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ์šฉ์ž์˜ ๋ฆฌ์†Œ์Šค ์กฐํšŒ ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ”ํžˆ ์šฐ๋ฆฌ์—๊ฒŒ๋Š” '์†Œ์…œ ๋กœ๊ทธ์ธ'์œผ๋กœ ์ž˜ ์•Œ๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด '๋ฒˆ๊ฐœ์žฅํ„ฐ' ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š”,

 

์œ„์™€ ๊ฐ™์ด '๋ฒˆ๊ฐœ์žฅํ„ฐ'์˜ ๋…์ž์ ์ธ ํผ ๋กœ๊ทธ์ธ์„ ์ง„ํ–‰ํ•˜์ง€ ์•Š๋”๋ผ๋„, '์นด์นด์˜ค, ํŽ˜์ด์Šค๋ถ, ๋„ค์ด๋ฒ„'์™€ ๊ฐ™์€ ์„œ๋“œํŒŒํ‹ฐ ํ”„๋กœ๋ฐ”์ด๋”๋“ค์—๊ฒŒ ์ธ์ฆ ๊ณผ์ •์„ ์œ„์ž„ํ•˜๊ณ , ์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„ํ•ด๋ƒ…๋‹ˆ๋‹ค. 

 

๊ทธ ์ค‘, OAuth2๋ผ๊ณ  ๋ถˆ๋ฆฌ์šฐ๋Š” ์ด์œ ๋Š” ๋‹น์—ฐํžˆ๋„ ์ด์ „ ๋ฒ„์ „์ด ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— '2'๋ผ๋Š” ๋ช…์นญ์ด ๋ถ™์—ˆ๊ฒ ์ฃ ? 2010๋…„ IETF์—์„œ 'OAuth 1.0' ๊ณต์‹ ํ‘œ์ค€์•ˆ์ด RFC 5849๋กœ ๋ฐœํ‘œ๋˜์—ˆ์œผ๋ฉฐ, OAuth์˜ ์„ธ์…˜ ๊ณ ์ • ๊ณต๊ฒฉ์„ ๋ณด์™„ํ•œ 'OAuth 1.0a'๋ฅผ ๊ฑฐ์ณ, ํ˜„์žฌ๋Š” OAuth์˜ ๊ตฌ์กฐ์ ์ธ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•˜๊ณ , ํ•ต์‹ฌ ์š”์†Œ๋งŒ์„ ์ฐจ์šฉํ•œ ์œ ์‚ฌ ํ”„๋กœํ† ์ฝœ WRAP(Web Resource Access Protocol)์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐœํ‘œํ•œ 'OAuth 2.0(RFC 6749, RFC 6750)'๊ฐ€ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฌํ•œ OAuth2.0์„ ํ†ตํ•ด ์„œ๋“œ ํŒŒํ‹ฐ ํ”„๋กœ๋ฐ”์ด๋”์—๊ฒŒ ์ธ์ฆ๊ณผ ์ธ๊ฐ€๋ฅผ ์œ„์ž„ํ•จ์œผ๋กœ์จ, ํด๋ผ์ด์–ธํŠธ(OAuth2 Client)์— ์ ‘๊ทผ ํ† ํฐ(OAuth2 Access Token)์„ ๋ฐœ๊ธ‰ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๊ตฌ์กฐ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

โœ… OAuth2.0์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋‹จ์–ด ์ •๋ฆฌ

OAuth2.0์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋‹จ์–ด๋“ค์— ๋Œ€ํ•ด ์ •๋ฆฌ๋ฅผ ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. 

๋‹จ์–ด ์„ค๋ช… ์ถ”๊ฐ€ ์„ค๋ช…
Resource Owner ๋ฆฌ์†Œ์Šค ์†Œ์œ ์ž, ์‰ฝ๊ฒŒ ํ‘œํ˜„ํ•˜๋ฉด ํŠน์ • ์„œ๋“œํŒŒํ‹ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํšŒ์›์ด๋ฉด์„œ, ์šฐ๋ฆฌ์˜ ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์„œ๋“œํŒŒํ‹ฐ ํ”„๋กœ๋ฐ”์ด๋”์˜ ๋ณดํ˜ธ๋œ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ž๊ฒฉ์„ ๋ถ€์—ฌํ•ด ์ฃผ๋Š” ์ฃผ์ฒด์ด๋ฉฐ, OAuth2 ํ”„๋กœํ† ์ฝœ ํ๋ฆ„์—์„œ๋Š” Client๋ฅผ ์ธ์ฆํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
ํ•ด๋‹น ์ธ์ฆ์ด ์™„๋ฃŒ๋˜๋ฉด ๊ถŒํ•œ ์„œ๋ฒ„๋ฅผ ๊ฑฐ์ณ ๊ถŒํ•œ ํš๋“ ์ž๊ฒฉ์„ Client์—๊ฒŒ ๋ถ€์—ฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
Client ํด๋ผ์ด์–ธํŠธ, OAuth2์™€ ์—ฐ๊ด€๋œ ์„œ๋ฒ„(Authorization Server, Resource Server)์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์š”์ฒญํ•˜๋Š” ์„œ๋น„์Šค๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. 'ํด๋ผ์ด์–ธํŠธ'๋ผ๋Š” ์ด๋ฆ„ ๋•Œ๋ฌธ์— ํ˜ผ๋™์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, OAuth2 Server์— ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ์ฃผ์ฒด๊ฐ€ OAuth2 Client๊ฐ€ ๋˜๋ฏ€๋กœ, ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์—์„œ๋Š” NEO ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๊ฐ€ Client์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
Provider, Server ํ”„๋กœ๋ฐ”์ด๋”, OAuth2 ์„œ๋ฒ„(Authorization + Resource)๋ฅผ ๊ตฌํ˜„ํ•จ์œผ๋กœ์จ OAuth2 ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ์„œ๋“œํŒŒํ‹ฐ ์ œ๊ณต์ž๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ naver, kakao, google, facebook, github, okta ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
Authorization Server ๊ถŒํ•œ ์„œ๋ฒ„, Resource Owner๋ฅผ ์ธ์ฆํ•˜๋ฉฐ Client์—๊ฒŒ Access Token์„ ๋ฐœ๊ธ‰ํ•ด์ค๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์— ๋”ฐ๋ผ Authorization Server์™€ Resource Server๋Š” ์•„ํ‚คํ…์ณ ๋ณ€๋™ ๊ฐ€๋Šฅ
Resource Server ์ž์› ์„œ๋ฒ„, ์‚ฌ์šฉ์ž์˜ ๋ณดํ˜ธ๋œ ์ž์›์„ ์†Œ์ง€ํ•˜๊ณ  ์žˆ๋Š” ์„œ๋ฒ„๋กœ ๊ถŒํ•œ ์„œ๋ฒ„์—์„œ ์šฐ์„  Access Token์„ ๋ฐ›์•„์•ผ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์— ๋”ฐ๋ผ Authorization Server์™€ Resource Server๋Š” ์•„ํ‚คํ…์ณ ๋ณ€๋™ ๊ฐ€๋Šฅ
Authorization Grant ๊ถŒํ•œ ํš๋“ ์ž๊ฒฉ, Resource Server์— ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ AccessToken์„ ๋ฐœ๊ธ‰ ๋ฐ›๊ธฐ ์ด์ „์— ๋ฐœ๊ธ‰ ๋ฐ›๋Š” ๊ถŒํ•œ ์Šน์ธ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์„ค๋ช…์€ ์•„๋ž˜ "OAuth2.0 Authorization Code Grant ๋ฐฉ์‹"
Access Token ์ ‘๊ทผ ํ† ํฐ, ํ•ด๋‹น ์ ‘๊ทผ ํ† ํฐ์„ ํ†ตํ•ด Resource Server๋กœ๋ถ€ํ„ฐ Resource Owner์˜ ์ •๋ณด๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. NEO์—์„œ ๋ณ„๋„๋กœ ๋ฐœ๊ธ‰ํ•˜๋Š” JWT Access Token์ด ์กด์žฌํ•˜๋ฏ€๋กœ, ๋‘ ๊ฐœ๋…์„ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๊ธ€์—์„œ๋Š” 'OAuth2 Access Token'์œผ๋กœ ๋ถ€๋ฅด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

 

โœ… OAuth2.0 Authorization Code Grant ๋ฐฉ์‹

 

https://wildeveloperetrain.tistory.com/247

 

Authorization Code Grant ๋ฐฉ์‹์€ OAuth2.0์—์„œ ๊ฐ€์žฅ ๋ณดํŽธ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ธ์ฆ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

์œ„์˜ ์ธ์ฆ ๋ฐฉ์‹ ๋„์‹ํ™” ๊ทธ๋ฆผ์„ ์‚ดํŽด๋ณด๋ฉด, ์ด ํ”„๋กœ์„ธ์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

๐Ÿ™‹๐Ÿป Authorization Code Grant Process

1. OAuth2.0 Client(NEO ๋ฐฑ์—”๋“œ)๊ฐ€ Authorization Server์— ์ ‘๊ทผ ๊ถŒํ•œ์„ ์š”์ฒญ(API ์š”์ฒญ)ํ•ฉ๋‹ˆ๋‹ค.
1-1. ์š”์ฒญ ์‹œ ๋ฐœ๊ธ‰ํ•œ client_id, redirect_url, response_type=code๋ฅผ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ํฌํ•จํ•œ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
1-2. ํ”„๋กœ๋ฐ”์ด๋”๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ž์ฒด ๋กœ๊ทธ์ธ ํผ ํŒ์—…์„ ์ถœ๋ ฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. (ex. ์นด์นด์˜ค ๋กœ๊ทธ์ธ ํผ, ๋„ค์ด๋ฒ„ ๋กœ๊ทธ์ธ ํผ ๋“ฑ.)

2. Resource Owner๊ฐ€ ํ”„๋กœ๋ฐ”์ด๋”๊ฐ€ ๋„์šด ๋กœ๊ทธ์ธ ํผ์„ ํ†ตํ•ด ๋กœ๊ทธ์ธ์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.
2-1. Authorization Server๋Š” ๊ถŒํ•œ ๋ถ€์—ฌ ์ฝ”๋“œ ์š”์ฒญ ์‹œ ์ „๋‹ฌ๋ฐ›์€ redirect_uri๋กœ Authorization Code(๊ถŒํ•œ ๋ถ€์—ฌ ์Šน์ธ ์ฝ”๋“œ)๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
2-2. ๊ถŒํ•œ ๋ถ€์—ฌ ์Šน์ธ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ธ์ฆ ๋ฐ ์ž์›์„œ๋ฒ„์— ์ ‘๊ทผํ•  ๋•Œ ํ•„์š”ํ•œ OAuth2 Access Token์„ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ๊ถŒํ•œ ๋ถ€์—ฌ ์Šน์ธ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ง€๊ณ , Authorization Server์— OAuth2 Access Token์„ ํšจ์ฒญํ•ฉ๋‹ˆ๋‹ค.
3-1. ์š”์ฒญ ์‹œ ๋ฐœ๊ธ‰ํ•œ client_id, redirect_url, grant_type, code(๊ถŒํ•œ ๋ถ€์—ฌ ์Šน์ธ ์ฝ”๋“œ)๋ฅผ ์ฟผ๋ฆฌ ํŒŒ๋ฆฌ๋ฏธํ„ฐ๋กœ ํฌํ•จํ•œ API ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
3-2. ์„ฑ๊ณต์ ์œผ๋กœ ์ธ์ฆ๋˜๋ฉด, OAuth2 Access Token์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

4. OAuth2 Access Token์„ ์†Œ์ง€ํ•œ Client๋Š” Resource Server์—๊ฒŒ ๋ณดํ˜ธํ•˜๊ณ  ์žˆ๋Š” Resource Onwer์˜ ์‚ฌ์šฉ์ž ์ž์›์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

 

 

๐Ÿค” Access Token์„ ํš๋“ํ•˜๋Š” ๊ณผ์ •์—์„œ Authorization Code ๋ฐœ๊ธ‰ ๊ณผ์ •์ด ๋“ค์–ด๊ฐ„ ์ด์œ ?

[๋‚ด์šฉ ์ถœ์ฒ˜ : https://wildeveloperetrain.tistory.com/247]

Authorization Code๋ฅผ ๋ฐœ๊ธ‰๋ฐ›๋Š” ๊ณผ์ •์ด ์ƒ๋žต๋˜๊ณ  OAuth2 Access Token์„ ๋ฐ”๋กœ ๋ฐœ๊ธ‰๋ฐ›๋Š”๋‹ค๋ฉด,
Authorization Server๋Š” ๊ถŒํ•œ ๋ถ€์—ฌ ์ฝ”๋“œ ์š”์ฒญ ์‹œ ์ „๋‹ฌ๋ฐ›์€ redirect_uri๋กœ OAuth2 Access Token์„ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Redirect URI์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ URI ์ž์ฒด์— ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์–ด ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ• ๋ฐ–์— ์—†์œผ๋ฉฐ, ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ์ธ OAuth2 Access Token์ด ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด ๋ฐ”๋กœ ๋…ธ์ถœ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Authorization Code ๋ฐœ๊ธ‰ ๊ณผ์ •์ด ์ถ”๊ฐ€๋œ ๊ฒฝ์šฐ, redirect uri๋กœ ์ „๋‹ฌ๋œ Authorization Code(2-1)๋ฅผ ๋ฐฑ์—”๋“œ ๋ ˆ๋ฒจ์—์„œ ํ•ด๋‹น ์Šน์ธ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•œ API ์š”์ฒญ์œผ๋กœ OAuth2 Access Token์„ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

์ด ๊ณผ์ •์„ ํ†ตํ•ด ๋ฐฑ์—”๋“œ ์‚ฌ์ด์—์„œ OAuth2 Access Token์ด ์ „๋‹ฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์•ก์„ธ์Šค ํ† ํฐ์˜ ํƒˆ์ทจ ์œ„ํ—˜์ด ์ค„์–ด๋“œ๋Š” ๋“ฑ, ๋‹ค๋ฅธ ๋ฐฉ์‹์— ๋น„ํ•ด ๋ณด์•ˆ์ ์œผ๋กœ ์•ˆ์ „ํ•˜๋‹ค๋Š” ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค.


<Authorization Code Grant ๋ฐฉ์‹ ์˜ˆ์‹œ>
Redirect URI: https://api.neo.com/callbackURL
ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ Authorization Code๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ: https://api.neo.com/callbackURL?code=abc123
(code๋Š” ๋…ธ์ถœ๋˜์–ด๋„ ๋œ ์œ„ํ—˜)

<Implicit Grant ๋ฐฉ์‹ ์˜ˆ์‹œ>
Redirect URI: https://api.neo.com/callbackURL
Access Token์ด ๋ฐ”๋กœ URI์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ: https://api.neo.com/callbackURL#access_token=xyz456
(OAuth Access Token์ด ์ง์ ‘ ๋…ธ์ถœ)

 

 

NEO๋Š” Spring OAuth2 Client๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์œ„์™€ ๊ฐ™์€ Authorization Code Grant ๋ฐฉ์‹์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฐฉ์‹ ์™ธ์—๋„ 3๊ฐ€์ง€ ๋ฐฉ์‹์ด ๋” ์žˆ๋Š”๋ฐ, ์ถ”๊ฐ€์ ์œผ๋กœ ์•Œ๊ณ  ์‹ถ์€ ๋ถ„๋“ค์€ ์•„๋ž˜์˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

 

OAuth, OAuth2 ๊ฐœ๋…๊ณผ ๋™์ž‘ ๋ฐฉ์‹ ์ •๋ฆฌ

OAuth, OAuth2 ๊ฐœ๋…๊ณผ ๋™์ž‘ ๋ฐฉ์‹ ์ •๋ฆฌ Spring Security + OAuth2๋ฅผ ํ†ตํ•œ ์†Œ์…œ ๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•˜๋˜ ์ค‘, oauth์˜ ๊ฐœ๋…๊ณผ ์ด๋ก ์ ์ธ ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•ด์„œ ์ž์„ธํ•˜๊ฒŒ ์•Œ๊ณ  ์‹ถ์–ด ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. 1. OAuth, OAuth2.0 ์ด๋ž€

wildeveloperetrain.tistory.com

 

 

โœ… Spring OAuth2 Client?

 

Spring์—์„œ๋Š” Security์™€ ํ•จ๊ป˜ OAuth2 Client ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. OAuth2 Client ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” OAuth2 Client๋กœ์จ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๋‚ด์šฉ์„ ์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

 

ํ”„๋กœ๋ฐ”์ด๋” ๋กœ๊ทธ์ธ ํผ์œผ๋กœ ์ด๋™์‹œ์ผœ์ฃผ๋Š” ์—”๋“œํฌ์ธํŠธ ์ž๋™ ์ƒ์„ฑ ๋ถ€ํ„ฐ, ๊ถŒํ•œ ๋ถ€์—ฌ ์Šน์ธ ์ฝ”๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Access Token ๋ฐœ๊ธ‰ ๋ฐ›๊ธฐ ๊ธฐ๋Šฅ์„ ์ƒ์„ธํ•œ ๊ตฌํ˜„ ์—†์ด ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, OAuth2 Access Token์„ ์‚ฌ์šฉํ•ด ์ž์›์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์ž์›์„ ๋‹ค๋ฃจ๋Š” ์„œ๋น„์Šค๋ฅผ ์ถ”๊ฐ€ ๊ตฌํ˜„ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ์œ„์˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ชจ๋‘ ์†์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋งŒ์•ฝ OAuth2 Client ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—†๋‹ค๋ฉด ๊ฐ ํ”„๋กœ๋ฐ”์ด๋”๋“ค์˜ API Docs๋ฅผ ํ™•์ธํ•ด์„œ, ๊ฐ ๊ณผ์ •์— ํ•ด๋‹นํ•˜๋Š” API๋ฅผ ์ง์ ‘ ํ†ต์‹ ํ•˜๋ ค RestTemplete๋‚˜ WebClient๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์—”๋“œํฌ์ธํŠธ ์ƒ์„ฑ์„ ์œ„ํ•œ ์ปจํŠธ๋กค๋Ÿฌ ์ƒ์„ฑ ๋“ฑ์˜ ํด๋ž˜์‹ํ•œ ๊ตฌํ˜„์ด ํ•„์š”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ OAuth2 Client ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์†Œ์…œ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜๊ธฐ๊ฐ€ ๋”์šฑ ์ˆ˜์›”ํ•ด์ง‘๋‹ˆ๋‹ค.

Spring OAuth2 Client๊ฐ€ ํ•˜๋Š” ์—ญํ• ์€ ๋’ค์— ์ด์–ด์ง€๋Š” ํฌ์ŠคํŒ…์—์„œ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๐Ÿ”ง JWT Token

โœ… JWT Token์ด๋ž€?

 

JWT(Json Web Token)์€ ๋ง ๊ทธ๋Œ€๋กœ ์›น์—์„œ ์‚ฌ์šฉ๋˜๋Š” JSON ํ˜•์‹์˜ ํ† ํฐ์— ๋Œ€ํ•œ ํ‘œ์ค€ ๊ทœ๊ฒฉ์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ(authentication) ๋˜๋Š” ์ธ๊ฐ€(authorization) ์ •๋ณด๋ฅผ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„์— ์•ˆ์ „ํ•˜๊ฒŒ ์ฃผ๊ณ  ๋ฐ›๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

NEO์—์„œ๋Š” OAuth2.0์„ ํ†ตํ•ด OAuth2 Access Token์„ ํš๋“ํ•˜๊ณ  ๋‚˜๋ฉด, ํ•ด๋‹น Access Token์„ ์šฐ๋ฆฌ NEO ์„œ๋น„์Šค์— ์ธ๊ฐ€ํ•  ๋•Œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ณ„๋„์˜ JWT Access Token์„ ๋ฐœ๊ธ‰ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

 

https://jwt.io/

 

์œ„๋Š” JWT ํ† ํฐ์˜ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. Encoded์™€ Decoded ํŒŒํŠธ๋ฅผ ๋‚˜๋ˆ ์„œ ๋ด…์‹œ๋‹ค.

 

๐Ÿค” Encoded

 JWT ํ† ํฐ์— ํ•„์š”ํ•œ ๋‚ด์šฉ๋“ค์„ ๋‹ด์•„ ์ธ์ฝ”๋”ฉ ๋œ ๊ธด ๋ฌธ์ž์—ด๋กœ, ๋ณดํ†ต ์šฐ๋ฆฌ๊ฐ€ JWT ํ† ํฐ์„ '์ „๋‹ฌ'์˜ ๋ฒ”์œ„์—์„œ ์–˜๊ธฐํ•  ๋•Œ ์ด ์ธ์ฝ”๋”ฉ๋œ JWT ํ† ํฐ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ธ์ฝ”๋”ฉ ๋œ JWT ํ† ํฐ์„ ์ „๋‹ฌํ•  ๋•Œ๋Š” HTTP์˜ Authorization ํ—ค๋” ํ˜น์€ Body์— ๋‹ด์•„์„œ ์ „๋‹ฌํ•˜๋ฉฐ,

ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„๋กœ JWT ํ† ํฐ์„ ์ „๋‹ฌํ•  ๋•Œ ํ•ด๋‹น ๋ฌธ์ž์—ด์„ Authorization Header์— ์•ž์— "Bearer "๋ผ๋Š” ๋ฌธ์ž์—ด์„ ์ถ”๊ฐ€ํ•ด ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค.

 

์ž˜ ๋ณด๋ฉด, ์ธ์ฝ”๋”ฉ๋œ JWT ํ† ํฐ์€ ๊ฐ ํŒŒํŠธ๊ฐ€ '.'์œผ๋กœ ๊ตฌ๋ถ„๋˜์–ด ์žˆ์œผ๋ฉฐ ๊ฐ๊ฐ ํ—ค๋”, ํŽ˜์ด๋กœ๋“œ, ์‹œ๊ทธ๋‹ˆ์ฒ˜ ์ˆœ์„œ๋Œ€๋กœ ์ธ์ฝ”๋”ฉ ๋œ ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆผ์˜ ์ƒ‰์ƒ์„ ๋ณด๋ฉด ์ข€ ๋” ํ™•์—ฐํžˆ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๐Ÿค” Decoded

JWT ํ† ํฐ์˜ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ์ธ์ฝ”๋”ฉ ๋˜๊ธฐ ์ „์˜ JWT ํ† ํฐ์˜ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค. JWT ํ† ํฐ์„ ์ƒ์„ฑํ•  ๋•Œ ์œ„์™€ ๊ฐ™์ด Header, Payload, Signature์˜ 3์š”์†Œ๋ฅผ ๊ตฌ์„ฑํ•ด ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉฐ, ์ธ์ฝ”๋”ฉ ๋œ JWT ํ† ํฐ์„ Decodeํ•˜๋ฉด ์—ญ์‹œ๋‚˜ Header, Payload, Signature์˜ ๊ฐ’์„ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

- ํ—ค๋”(Header)

ํ•ด๋‹น ํ† ํฐ ์Šค์Šค๋กœ์— ๋Œ€ํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ธ์ฝ”๋”ฉ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ธ 'alg'์™€ ํ† ํฐ์˜ ์œ ํ˜•์ธ 'typ'๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

 

- ํŽ˜์ด๋กœ๋“œ(payload)

ํ† ํฐ์— ์‚ฝ์ž…ํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. JWT ํ† ํฐ์€ ์ •ํ•ด์ง„ ์ธ์ฝ”๋”ฉ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์˜ํ•ด ์‰ฝ๊ฒŒ ๋””์ฝ”๋”ฉ๋ฉ๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋‚˜ JWT ํ† ํฐ์— ๋Œ€ํ•ด ์‰ฝ๊ฒŒ ์ •๋ณด๋ฅผ ์—ด๋žŒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํŽ˜์ด๋กœ๋“œ์—๋Š” ๊ฐ€๋Šฅํ•œ ๋ˆ„๊ตฌ์ธ์ง€ ์‹๋ณ„ ๊ฐ€๋Šฅํ•œ ์ตœ์†Œํ•œ์˜ ๋ฐ์ดํ„ฐ๋งŒ์„ ๋„ฃ์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ํด๋ ˆ์ž„(claim)์ด๋ผ๋Š” ๊ฐœ๋…์ด ๋‚˜์˜ค๋Š”๋ฐ, ์‰ฝ๊ฒŒ ํ‘œํ˜„ํ•˜๋ฉด ํŽ˜์ด๋กœ๋“œ์— ์ถ”๊ฐ€๋˜๋Š” ์ •๋ณด ์กฐ๊ฐ์˜ ๋‹จ์œ„๋ผ๊ณ  ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, JWT ํ† ํฐ์„ ์ƒ์„ฑํ•  ๋•Œ ๊ฐ ์‚ฌ์šฉ์ž๋ฅผ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” '์ด๋ฉ”์ผ'์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋„ฃ๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. 

๊ทธ๋ ‡๋‹ค๋ฉด JSON ๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•œ key-value์˜ ํ˜•ํƒœ๋กœ ํ•ด๋‹น ์กฐ๊ฐ์„ ์‚ฝ์ž…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ .

{
      "sub": "1234567890",
      "email": "aaaaa1234@gmail.com",
}

์œ„์™€ ๊ฐ™์€ ํŽ˜์ด๋กœ๋“œ๋Š” 'sub'์™€ 'email' ๋‘ ๊ฐœ์˜ ํด๋ ˆ์ž„์œผ๋กœ ์ด๋ฃจ์–ด์กŒ๋‹ค๊ณ  ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

- ์‹œ๊ทธ๋‹ˆ์ณ(Signature)

์‹œ๊ทธ๋‹ˆ์ณ๋Š” ํ—ค๋”์™€ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๊ฐ๊ฐ Base64 ์ธ์ฝ”๋”ฉ์„ ๊ฑฐ์นœ ๋ฌธ์ž์—ด๊ณผ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๊ฐ€ ์†Œ์ง€ํ•˜๊ณ  ์žˆ๋Š” Secret Key๋ฅผ ํฌํ•จํ•ด์„œ ๋‹ค์‹œ ์ธ์ฝ”๋”ฉํ•œ ๊ธด ๋ฌธ์ž์—ด์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ์‹œ๊ทธ๋‹ˆ์ณ๋Š” JWT ํ† ํฐ์— ํฌํ•จ์ด ๋˜๋ฉฐ, ์ถ”ํ›„ JWT ํ† ํฐ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

Secret Key๋Š” ์‹œ๊ทธ๋‹ˆ์ณ์˜ ์ผ๋ถ€๋ฅผ ๊ตฌ์„ฑํ•˜๊ฒŒ ๋˜๋Š” ๋ฌธ์ž์—ด๋กœ ๋žœ๋คํ•œ ๋ฌธ์ž์—ด๋กœ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ƒ์„ฑํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ธํ„ฐ๋„ท ์ƒ์˜ Key Generator๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹ค, ํ‚ค๋ณด๋“œ๋ฅผ ๋žœ๋คํ•˜๊ฒŒ ๊ธธ๊ฒŒ ์ž…๋ ฅํ•ด ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ Springboot ํ”„๋กœ์ ํŠธ์—์„œ Secret Key๋ฅผ application.yml์— ๋ณ„๋„๋กœ ์ €์žฅํ•ด ๋…ธ์ถœ๋˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

 

 

โœ… Access Token๊ณผ Refresh Token

 

JWT Access Token์€, JWT๋ฅผ ์‚ฌ์šฉํ•ด ํŠน์ • ์„œ๋น„์Šค์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์ธ์ฆ/์ธ๊ฐ€์˜ ์—ญํ• ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“œ๋Š” ๋งค๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค.

์œ„์˜ JWT Token์— ๋Œ€ํ•œ ๋‚ด์šฉ์„, ์–ด๋–ป๊ฒŒ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•˜๊ณ  ์–ด๋–ป๊ฒŒ ํ•ด๋‹น ํ† ํฐ์„ ๊ฒ€์ฆํ•˜๋Š”์ง€๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ์‚ดํŽด๋ณด๋ฉฐ JWT Token์ด ์–ด๋–ป๊ฒŒ Access Token๋กœ ํ™œ์šฉ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์šฐ์„ , JWT ํ† ํฐ์„ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.

 

์œ„์—์„œ ์„ค๋ช…ํ•œ ๋‚ด์šฉ๋Œ€๋กœ, ํ—ค๋”์™€ ํŽ˜์ด๋กœ๋“œ์— ๋‚ด์šฉ์„ ์ฑ„์›Œ๋„ฃ๊ฒŒ ๋˜๊ณ  ์‹œ๊ทธ๋‹ˆ์ณ๋Š” ์ด๋ ‡๊ฒŒ ์ž…๋ ฅ๋œ ํ—ค๋” + ํŽ˜์ด๋กœ๋“œ + ์‹œํฌ๋ฆฟ ํ‚ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  JWT Token์€ ํ—ค๋”์™€ ํŽ˜์ด๋กœ๋“œ์™€ ์‹œ๊ทธ๋‹ˆ์ณ๋ฅผ ์ธ์ฝ”๋”ฉํ•ด ๋งŒ๋“ค์–ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ JWT Token์€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ Authorization ํ—ค๋” ํ˜น์€ Body๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ํด๋ผ์ด์–ธํŠธ๋Š” ํ•ด๋‹น JWT Token์„ ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ณด๊ด€์„ ํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€, ์„œ๋ฒ„์˜ API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์š”์ฒญ๊ณผ ํ•จ๊ป˜ ํ—ค๋”์— ํ•ด๋‹น ํ† ํฐ์„ ๋‹ด์•„์„œ ์ „์†ก์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

 

์„œ๋ฒ„์— ๋„์ฐฉํ•œ JWT Token์€ ๊ฒ€์ฆ ๊ณผ์ •์„ ๊ฑฐ์น˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ฒ€์ฆ ๊ณผ์ •์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

1. ์„œ๋ฒ„์— ๋„์ฐฉํ•œ JWT Token์„ ๋””์ฝ”๋”ฉํ•ฉ๋‹ˆ๋‹ค.
2. ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ JWT ํ† ํฐ์˜ ์‹œ๊ทธ๋‹ˆ์ณ๋ฅผ '์›๋ณธ ์‹œ๊ทธ๋‹ˆ์ณ'๋ผ๊ณ  ์ง€์นญํ•ฉ๋‹ˆ๋‹ค.
3. ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ JWT ํ† ํฐ์˜ ํ—ค๋”์™€ ํŽ˜์ด๋กœ๋“œ๋ฅผ ์–ป์–ด์˜ต๋‹ˆ๋‹ค.
4. ์„œ๋ฒ„์— ์ €์žฅ๋œ secret key๋ฅผ ๊ฐ€์ง€๊ณ  'ํ…Œ์ŠคํŠธ ์‹œ๊ทธ๋‹ˆ์ณ'๋ฅผ ์ƒ์„ฑํ•ด๋ƒ…๋‹ˆ๋‹ค.
5. ์›๋ณธ ์‹œ๊ทธ๋‹ˆ์ณ์™€ ํ…Œ์ŠคํŠธ ์‹œ๊ทธ๋‹ˆ์ณ๋ฅผ ์„œ๋กœ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.
    5-1. ๋‘ ์„œ๋ช…์ด ๊ฐ™๋‹ค๋ฉด ๊ฒ€์ฆ ํ†ต๊ณผ์ž…๋‹ˆ๋‹ค.
    5-2. ๋‘ ์„œ๋ช…์ด ๋‹ค๋ฅด๋‹ค๋ฉด ๊ฒ€์ฆ ์‹คํŒจ์ž…๋‹ˆ๋‹ค. (ํ—ค๋” ํ˜น์€ ํŽ˜์ด๋กœ๋“œ ์œ„์กฐ ๋“ฑ)

 

์„œ๋ฒ„๋Š” ์š”์ฒญ๊ณผ ํ—ค๋”์— ํฌํ•จ๋œ JWT ํ† ํฐ์„ ๊ฐ€์ง€๊ณ  ์šฐ๋ฆฌ๊ฐ€ ์•„๋Š” ์‚ฌ์šฉ์ž์ธ์ง€, ํ•ด๋‹น ์‚ฌ์šฉ์ž๊ฐ€ ์ด ์„œ๋น„์Šค์— ์ ‘๊ทผํ•  ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ํŒ๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋Ÿฌํ•œ ๊ณผ์ •์„ JWT ํ† ํฐ์„ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JWT ํ† ํฐ์„ ๊ฒ€์ฆํ–ˆ์„ ๋•Œ ์œ ํšจํ•˜๋‹ค๋ฉด ์šฐ๋ฆฌ ์„œ๋น„์Šค๊ฐ€ ๋งŒ๋“ค์–ด๋‚ธ ํ† ํฐ์ด๋ฏ€๋กœ(์‹œํฌ๋ฆฟ ํ‚ค๊ฐ€ ๋…ธ์ถœ๋˜์ง€ ์•Š๋Š” ์ด์ƒ) ์ธ์ฆ์„, ํŽ˜์ด๋กœ๋“œ์— ์‚ฌ์šฉ์ž ์—ญํ• ์„ ํฌํ•จํ•œ๋‹ค๋ฉด ์ธ๊ฐ€ ์—ญ์‹œ JWT ํ† ํฐ์„ ํ†ตํ•ด ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ JWT ํ† ํฐ์€ Access Token์œผ๋กœ์จ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

JWT ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„์— ๋ณ„๋‹ค๋ฅธ ์ธ์ฆ ์ •๋ณด ์ €์žฅ ๊ณต๊ฐ„์ด ์—†๋”๋ผ๋„ ์ž์ฒด์ ์œผ๋กœ ์ธ์ฆ/์ธ๊ฐ€๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ ์€ ์„ธ์…˜๊ณผ ๋‹ค๋ฅธ ๊ต‰์žฅํ•œ ์ฐจ๋ณ„์ ์œผ๋กœ ์ž‘์šฉํ•ด JWT Token ๋ฐฉ์‹์ด ์ธ๊ธฐ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์ด๋Ÿฐ Access Token์—๋„ ๋‹จ์ ์€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น Access Token์ด ๋‹ค๋ฅธ ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ํƒˆ์ทจ๋˜์–ด ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์„œ๋ฒ„์—์„œ๋Š” ํ•ด๋‹น ํ† ํฐ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ณ„๋„๋กœ ์ €์žฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์„œ๋ฒ„๋กœ ๋“ค์–ด์˜จ ์š”์ฒญ์ด ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๊ฐ€ ํƒˆ์ทจํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ธ์ง€, ์‹ค์ œ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ธ์ง€ ๊ตฌ๋ณ„ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

๋ฌผ๋ก  Access Token์˜ ๊ด€๋ฆฌ๋ฅผ ์ œ๋Œ€๋กœ ๋ชปํ•œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ž˜๋ชป์ด ์žˆ์ง€๋งŒ, ํƒˆ์ทจ๊ฐ€ ์˜์‹ฌ๋˜๋Š” ์ƒํ™ฉ์— ๋ณ„๋„์˜ ์ €์žฅ ๊ณต๊ฐ„์ด ์—†๋‹ค๋ฉด ์„œ๋ฒ„์ธก์—์„œ๋„ ํ›„์† ์กฐ์น˜๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ๋‹จ์ ์„ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜์˜จ ์•„์ด๋””์–ด๊ฐ€ ๋ฐ”๋กœ, "Access Token์˜ ๋งŒ๋ฃŒ์‹œ๊ฐ„์„ ์งง๊ฒŒ ์„ค์ •ํ•ด์„œ ํƒˆ์ทจ๊ฐ€ ๋˜๋”๋ผ๋„ ํ”ผํ•ด๋ฅผ ์ตœ์†Œํ™” ํ•˜์ž"๋ผ๋Š” ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค.

ํ•ด๋‹น ๋ฐฉ๋ฒ•์€ ํšจ๊ณผ์ ์ด์ง€๋งŒ, ๋‹จ์ˆœํžˆ Access Token์˜ ์œ ํšจ๊ธฐ๊ฐ„์„ ์งง๊ฒŒ ์„ค์ •ํ•œ๋‹ค๋ฉด ๊ธฐ๊ฐ„์ด ๋งŒ๋ฃŒ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ๋กœ๊ทธ์ธ์„ ํ•˜๋Š”, ๋ถˆํŽธํ•œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์•ˆ๊ฒจ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ ์ถ”๊ฐ€๋œ ๊ฐœ๋…์ด ๋ฐ”๋กœ, 'Refresh Token'์ž…๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋กœ๊ทธ์ธ์„ ํ•˜๋ฉด, ์„œ๋ฒ„๋Š” Access Token๊ณผ Refresh Token์„ ๊ฐ™์ด ์ง€๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋‘ ํ† ํฐ์˜ ๋งŒ๋ฃŒ๊ธฐ๊ฐ„์€, Access Token์ด ํ›จ์”ฌ ์งง๊ณ  Refresh Token์€ ๋งŒ๋ฃŒ ๊ธฐ๊ฐ„์ด ๊ธด ๊ตฌ์กฐ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ์Šต๋‹ˆ๋‹ค.

 

์–ด๋А ์ˆœ๊ฐ„, Access Token์ด ๋งŒ๋ฃŒ๋˜๊ณ  ์‚ฌ์šฉ์ž๋Š” ํ•ด๋‹น ํ† ํฐ์œผ๋กœ ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ๋งŒ๋ฃŒ๋œ ์‚ฌ์‹ค์„ ์•Œ์•„์ฐจ๋ฆฌ๊ณ , ์š”์ฒญ์„ ๋ฐ˜๋ คํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ๋‹ค์‹œ ๋กœ๊ทธ์ธ์„ ์œ ๋„ํ•˜์ง€ ์•Š๊ณ  Refresh Token์„ ํ•จ๊ป˜ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. Refresh Token์ด ์œ ํšจํ•˜๊ณ  Access Token์ด ๋งŒ๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด ์ƒˆ๋กœ์šด Access Token์„ ๋ฐœ๊ธ‰ํ•ด์ฃผ๋Š” ๊ตฌ์กฐ์ฃ .

 

์ด๋Ÿฐ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์žฆ์€ ๋กœ๊ทธ์ธ์„ ์œ ๋„ํ•˜์ง€ ์•Š๊ณ , ํƒˆ์ทจ๋œ Access Token์— ๋Œ€ํ•ด์„œ ์ตœ์†Œํ•œ์˜ ํ”ผํ•ด๋กœ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์ด ๋ฐฉ๋ฒ• ์—ญ์‹œ Refresh Token๋„ ํ•จ๊ป˜ ํƒˆ์ทจ๊ฐ€ ๋œ๋‹ค๋ฉด ์„œ๋ฒ„ ์ธก์—์„œ๋Š” ์† ์“ธ ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. (ํ† ํฐ ์ •๋ณด์— ๋Œ€ํ•œ ๋‚ด์šฉ์˜ ์ €์žฅ ๊ณต๊ฐ„์ด ์—†๋Š” ๊ฒฝ์šฐ.)

 

 

โœ… Refresh Token์˜ ์ข…๋ฅ˜

 

Refresh Token์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๐Ÿ™‹๐Ÿป 1. ๊ธฐ์กด JWT(Claim) ๋ฐฉ์‹์˜ Refresh Token

๊ธฐ์กด์˜ JWT ํ† ํฐ์„ ํ™œ์šฉํ•ด์„œ Refresh Token์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์— ์ƒ์„ฑํ•˜๋˜ ๋ฐฉ์‹ ๊ทธ๋Œ€๋กœ ์ƒ์„ฑ์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ, ๋งŒ๋ฃŒ๊ธฐํ•œ ์—ญ์‹œ ์‰ฝ๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Access Token๊ณผ๋Š” ๋ณ„๊ฐœ๋กœ ์ƒˆ๋กœ์šด Access Token์„ ๋ฐœ๊ธ‰ ๋ฐ›๊ธฐ ์œ„ํ•œ ํ† ํฐ์ด ์กด์žฌ ์˜์˜์ด๋ฏ€๋กœ Access Token์— ๋“ค์–ด๊ฐ”๋˜ ์ผ๋ถ€ ํด๋ ˆ์ž„ ์—ญ์‹œ ์ œ๊ฑฐํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค. 

๋‹ค๋งŒ Access Token๊ณผ Refresh Token์ด ๋ชจ๋‘ ํƒˆ์ทจ๋˜์—ˆ์„ ๊ฒฝ์šฐ์—๋Š” ๋ณ„๋„๋กœ ์† ์“ธ ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ JWT ํ† ํฐ์€ Stateless ํ•˜๋‹ˆ๊นŒ ๋ง์ด์ฃ . 

 

๐Ÿ™‹๐Ÿป 2. UUID๋ฅผ ํ™œ์šฉํ•œ Refresh Token

UUID๋ฅผ ๋žœ๋คํ•˜๊ฒŒ ์ƒ์„ฑํ•ด ํ•ด๋‹น ๋ฌธ์ž์—ด์„ Refresh Token์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ UUID๋Š” JWT ํ† ํฐ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž์ฒด๋กœ ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•ด๋‹น ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๊ณง ์„œ๋ฒ„์— ๋ณ„๋„์˜ ํ† ํฐ ์ €์žฅ ๊ณต๊ฐ„์„ ๋งˆ๋ จํ•œ๋‹ค๋Š” ์˜๋ฏธ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. 

 

NEO์—์„œ๋Š” 2๋ฒˆ, UUID๋ฅผ ํ™œ์šฉํ•œ Refresh Token์„ ์„ ํƒํ–ˆ๊ณ , ์ €์žฅ ๊ณต๊ฐ„์œผ๋กœ๋Š” Redis๋ฅผ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.

์„ ํƒ ์‚ฌ์œ ๋Š”, ์šฐ์„  ์ธ๋ฉ”๋ชจ๋ฆฌ key-value ์บ์‹œ๋กœ์„œ ์ƒ‰์ธ ์†๋„์—์„œ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ Redis ์บ์‹œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์–ธ์ œ๊นŒ์ง€ ์ €์žฅ๋  ์ง€ ๋งŒ๋ฃŒ๊ธฐ๊ฐ„์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์–ด ํ† ํฐ๊ณผ ๋น„์Šทํ•œ ๊ตฌ์กฐ๋กœ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ์ข‹๊ฒŒ ์ž‘์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ด์™€ ๊ฐ™์ด Refresh Token์ด ์„œ๋ฒ„์—์„œ ๋ณ„๋„ ์Šคํ† ๋ฆฌ์ง€๋กœ ๊ด€๋ฆฌ๋œ๋‹ค๋ฉด, ํŠน์ • ํ† ํฐ์˜ ์ ‘๊ทผ์„ ๋ง‰๋Š” 'black list' ๊ตฌํ˜„์„ ํ†ตํ•ด ๋ณด์•ˆ์„ ๋”์šฑ ๋” ๊ฐ•ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด Logout ์ดํ›„์—๋„ ์•„์ง ๋งŒ๋ฃŒ์‹œ๊ฐ„์ด ์ง€๋‚˜์ง€ ์•Š์€ ํ† ํฐ์— ๋Œ€ํ•ด ์ ‘๊ทผ์„ ๋ง‰๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ด์ง€์ฃ .

 

 

โœ… ๊ทธ๋Ÿผ ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋ณ„๋ฐ˜ ๋‹ค๋ฅผ ๊ฒƒ์ด ์—†๋„ค์š”?

 

์ด ์˜๊ฒฌ์— ์žˆ์–ด์„œ ๋„ˆ๋ฌด๋‚˜๋„ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. JWT ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ€์žฅ ํฐ ์ด์œ ๋Š” "์ธ์ฆ ์ •๋ณด๋ฅผ ๋ณ„๋„๋กœ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„์ด ์—†์–ด๋„ ๋œ๋‹ค, statelessํ•˜๋‹ค"์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ์žฅ์ ์ด ํ‡ด์ƒ‰๋˜์–ด ๊ฒฐ๊ตญ์—๋Š” ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ํฐ ์ฐจ์ด๊ฐ€ ์—†์–ด๋ณด์ž…๋‹ˆ๋‹ค.

 

๊ธฐ์กด์˜ JWT ํ† ํฐ์€ stateless ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ™•์žฅ์„ฑ์ด ๊ต‰์žฅํžˆ ์ข‹์•˜์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ์—ฌ๋Ÿฌ๋Œ€๋กœ ๋Š˜์–ด๋‚˜๋”๋ผ๋„ ๋ณ„๋„์˜ ์„ธ์…˜ ์„œ๋ฒ„๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์„ธ์…˜ ์„œ๋ฒ„๋ฅผ ์‹ ๊ฒฝ ์“ธ ํ•„์š”๊ฐ€ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ๊ทธ๋Ÿฌ๋‚˜ ๋ณ„๋„๋กœ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„์ด ์ƒ๊ฒผ๋‹ค๋Š” ๊ฒƒ์€ ์ด๋Ÿฌํ•œ ์ ์„ ์•ž์œผ๋กœ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ๊ตฌํ˜„์„ ํšŒ์˜์ ์ธ ์‹œ๊ฐ์œผ๋กœ ๋ณด์‹œ๋Š” ๊ฐœ๋ฐœ์ž๋ถ„๋“ค๋„ ๋งŽ์ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ์—๋„ JWT Token + UUID Refresh Token in Redis์˜ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด๋ณด์ž๋ฉด,

์ผ๋ฐ˜์ ์ธ ์„ธ์…˜ ๋ฐฉ์‹์— ๋น„ํ•ด ์„ธ์…˜ ์„œ๋ฒ„์— ๋Œ€ํ•œ '์š”์ฒญ' ์ž์ฒด๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ํฌ์ธํŠธ๋ฅผ ์ฃผ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์„ธ์…˜ ๋ฐฉ์‹์€ ์„ธ์…˜ ID๋ฅผ ๋‹ด์€ ์ฟ ํ‚ค์™€ ์š”์ฒญ์„ ํ•จ๊ป˜ ์ „์†กํ•˜๊ณ  ํ•ด๋‹น ์„ธ์…˜ ID๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ธ์…˜ ์„œ๋ฒ„์˜ ์Šคํ† ๋ฆฌ์ง€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์„ธ์…˜ ์„œ๋ฒ„์— ํ•ด๋‹น ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ์–ป์–ด์˜ค๋Š” ์š”์ฒญ์ด ํ•œ ๋ฒˆ, ๋ณธ๋ž˜ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›ํ•˜๋Š” ์š”์ฒญ์ด ํ•œ ๋ฒˆ ์ผ์–ด๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ JWT Token + UUID Refresh Token in Redis ๋ฐฉ์‹์˜ ๊ฒฝ์šฐ, JWT Access Token์— ๋Œ€ํ•ด์„œ๋Š” Redis๊ฐ€ ๋ณ„๋„๋กœ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ† ํฐ ์ž์ฒด์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋งŒ์œผ๋กœ ๋ณธ๋ž˜ ์š”์ฒญ์„ ํ–‰ํ•  ๊ฒƒ์ธ์ง€ ๋ฐ˜๋ คํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋งŒ์•ฝ ์„ธ์…˜ ์„œ๋ฒ„์˜ ์š”์ฒญ ์—ญ์‹œ ๋ถ€๋‹ด์ด ๊ฐ€๋Š” ํ”„๋กœ์ ํŠธ๋ผ๋ฉด ์œ ํšจํ•˜๊ฒŒ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์ด๋Ÿฌํ•œ ์ ๋ณด๋‹ค ๋‹ค๋ฅธ ํฌ์ธํŠธ๋ฅผ ํ›จ์”ฌ ์ค‘์š”ํ•˜๊ฒŒ ์—ฌ๊ธด๋‹ค๋ฉด ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ํ•ด๋‹น ์„œ๋น„์Šค์— ๋”์šฑ ์–ด์šธ๋ฆด ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์•„์ง ๊ฒฝํ—˜์ด ๋งŽ์ง€ ์•Š์€ ๊ฐœ๋ฐœ์ž๋ผ ์–ด๋–ค ์„œ๋น„์Šค์— ์–ด๋–ค ๋ฐฉ์‹์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ตœ์„ ์ธ์ง€ ๋‹ค์–‘ํ•œ ์˜๊ฒฌ์„ ๋“ฃ๊ณ  ์‹ถ๊ณ , ์ข‹์€ ๊ฒฝํ—˜์„ ์Œ“๊ณ  ์‹ถ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค ๋ฟ์ด๋„ค์š”.

 

์†Œํ”„ํŠธ์›จ์–ด ๊ณตํ•™์—์„œ '์€ํƒ„ํ™˜์€ ์—†๋‹ค' ๋ผ๋Š” ๋ง์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์šธ๋ฒ„๋ฆฐ, ๋Š‘๋Œ€์ธ๊ฐ„, ๋“œ๋ผํ˜๋ผ์™€ ๊ฐ™์€ ๊ดด๋ฌผ๋“ค์—๊ฒŒ ์€ํƒ„ํ™˜(one seeks bullets of silver)์€ ํ•œ๋ฒˆ์— ๋ฌด๋ ฅํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์ตœ๊ณ ์˜ ๋„๊ตฌ์ด๋‹ค.
- Fred Brooks, ใ€ŽSilver Bullet-Essence and Accidents of Software Engineeringใ€

ํ† ํฐ ๋ฐฉ์‹์€ ์„ธ์…˜ ๋ฐฉ์‹์„ ๋Œ€์ฒดํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜์˜จ ๊ฐœ๋…์ด์ง€๋งŒ, ์—ญ์‹œ๋‚˜ ์€ํƒ„ํ™˜์€ ์•„๋…”์Šต๋‹ˆ๋‹ค. 

๋‹ค์Œ์— ๊ธฐํšŒ๊ฐ€ ๋œ๋‹ค๋ฉด ์„ธ์…˜ ๋ฐฉ์‹๋„ ํ•œ ๋ฒˆ ๊ตฌํ˜„ํ•ด๋ณด๋ฉด์„œ ๊ฐ๊ฐ์˜ ์žฅ์ ์„ ์ข€ ๋” ์ฒด๊ฐํ•˜๊ณ  ์‹ถ๋„ค์š”.

 

 

โ˜•๏ธ ์ „์ฒด ํ”„๋กœ์„ธ์Šค ๋„์‹ํ™”

 

์•„๋ž˜์˜ ๊ทธ๋ฆผ์€ NEO์—์„œ ์‚ฌ์šฉ๋œ ์ „์ฒด ํ”„๋กœ์„ธ์Šค๋ฅผ ํ‘œํ˜„ํ•œ ๊ทธ๋ฆผ์ž…๋‹ˆ๋‹ค. ํ‘œํ˜„๋ ฅ์˜ ๋ฌธ์ œ๋กœ ์•ฝ๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฐธ๊ณ ๋งŒ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

 

 

Figma

Created with Figma

www.figma.com

 

 

โ˜•๏ธ ์—ฐ๊ด€ ํฌ์ŠคํŠธ

์—…๋ฐ์ดํŠธ ์˜ˆ์ •..
[โš™๏ธ Trouble Shooting] - [TS] Spring Security + Spring OAuth2 Client ์ ์šฉ ๊ณผ์ • ์ค‘ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

 

 

โ˜•๏ธ Reference

https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-token-claims
https://wildeveloperetrain.tistory.com/247
https://stackoverflow.com/questions/31309759/what-is-secret-key-for-jwt-based-authentication-and-how-to-generate-it

 

์ €์ž‘์žํ‘œ์‹œ ๋น„์˜๋ฆฌ ๋™์ผ์กฐ๊ฑด (์ƒˆ์ฐฝ์—ด๋ฆผ)

'๐ŸŒฑ ๋ฐฑ์—”๋“œ : Backend' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[QueryDSL] QueryDSL-JPA : JOIN ํ•˜๊ธฐ  (0) 2024.04.25
[QueryDSL] QueryDSL-JPA : @ElementCollection VO์— ๋Œ€ํ•œ JOIN  (1) 2024.04.23
[Spring] API ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ Swagger ๋„์ž…ํ•˜๊ธฐ (gradle ๊ธฐ์ค€)  (0) 2023.03.24
[Spring] @Transactional๊ณผ DB Lock์— DeepDive - (1) DB ํŠธ๋žœ์žญ์…˜, ์‚ฌ์šฉ๋ฐฉ๋ฒ•, ๊ฒฉ๋ฆฌ์ˆ˜์ค€, ์ „ํŒŒ ๋‹จ๊ณ„ ํ›‘์–ด๋ณด๊ธฐ  (0) 2023.03.21
[Spring] @ControllerAdvice์™€ @ExceptionHandler  (0) 2023.03.18
    '๐ŸŒฑ ๋ฐฑ์—”๋“œ : Backend' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
    • [QueryDSL] QueryDSL-JPA : JOIN ํ•˜๊ธฐ
    • [QueryDSL] QueryDSL-JPA : @ElementCollection VO์— ๋Œ€ํ•œ JOIN
    • [Spring] API ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ Swagger ๋„์ž…ํ•˜๊ธฐ (gradle ๊ธฐ์ค€)
    • [Spring] @Transactional๊ณผ DB Lock์— DeepDive - (1) DB ํŠธ๋žœ์žญ์…˜, ์‚ฌ์šฉ๋ฐฉ๋ฒ•, ๊ฒฉ๋ฆฌ์ˆ˜์ค€, ์ „ํŒŒ ๋‹จ๊ณ„ ํ›‘์–ด๋ณด๊ธฐ
    ๊ฐœ๋ฐœ์ž HOON
    ๊ฐœ๋ฐœ์ž HOON
    ์ข‹์€ ๋ฐฑ์—”๋“œ ์—”์ง€๋‹ˆ์–ด๊ฐ€ ๋˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ก์„ ๋ชจ์•˜์Šต๋‹ˆ๋‹ค. # ์ฃผ๋‹ˆ์–ด # ๋ฐฑ์—”๋“œ # ๊ฐœ๋ฐœ์ž

    ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”