Published on

๐Ÿ“… DayGrid

WEB : ๐Ÿ”—(๋ฐฐํฌ ์ค‘๋‹จ)
Github : ๐Ÿ”—

์„œ๋น„์Šค ์†Œ๊ฐœ

์ฃผ๊ฐ„ ๋ฐ ์›”๊ฐ„ ๋‹จ์œ„์˜ ์ผ์ •์„ ํ•œ๋ˆˆ์— ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๊ณ , ๋งž์ถคํ˜• ์ƒ‰์ƒ ๋ฐ ๋””๋ฐ์ด ์„ค์ •์ด ๊ฐ€๋Šฅํ•œ ์ผ์ • ๊ด€๋ฆฌ ์‚ฌ์ดํŠธ

์‚ฌ์šฉ ๊ธฐ์ˆ  ๋ฐ ๋„์ž… ์‚ฌ์œ 

React

UI ๊ฐœ๋ฐœ์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜๊ฐ€ ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ, ๋ถ„๋ฆฌ ๋ฐ ๊ฒฐํ•ฉ์„ ์šฉ์ดํ•˜๊ฒŒ ํ•ด์ฃผ์–ด ์ฝ”๋“œ ์œ ์ง€ ๊ด€๋ฆฌ๋ฅผ ๋ณด๋‹ค ๊ฐ„ํŽธํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ๋ฐฉ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

TypeScript

์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ์˜ค๋ฅ˜๋ฅผ ํ™•์ธํ•˜์—ฌ ์‹ค์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ณ , ๋ช…์‹œ์ ์ธ ์ •์ ํƒ€์ž… ์ง€์ •์œผ๋กœ ์˜๋„๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Redux

๋ชจ๋“  ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ์•ก์…˜์œผ๋กœ ์ •์˜ํ•˜๊ณ , ์•ก์…˜ ์ •๋ณด์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ๋ฆฌ๋“€์„œ์—์„œ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ์ƒํƒœ๋ฅผ ๋”์šฑ ์‰ฝ๊ฒŒ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์— ๊ธ์ •์ ์ธ ํšจ๊ณผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

React-Query

์„œ๋ฒ„ ์ƒํƒœ๋ฅผ ์‰ฝ๊ฒŒ ๊ฐ€์ ธ์˜ค๊ณ  ์บ์‹ฑ, ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ์–ด ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ตœ์ ํ™”ํ•˜๊ณ , ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Axios

fetch๋กœ๋„ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ์ œ๊ณตํ•˜์ง€๋งŒ, ๋”์šฑ ๋„“์€ ๋ธŒ๋ผ์šฐ์ € ์ง€์› ๋ฒ”์œ„, ์š”์ฒญ ๋ฐ ์‘๋‹ต ์ธํ„ฐ์…‰ํ„ฐ ๊ธฐ๋Šฅ, JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ํŒŒ์‹ฑ์„ ํ•ด์ฃผ๋Š” ๋“ฑ์˜ ์žฅ์ ์œผ๋กœ ์ธํ•ด ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.

Express

์„œ๋ฒ„ ๊ตฌํ˜„์ด ์ฒ˜์Œ์ด๋ผ ๊ฐ„๊ฒฐํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ๋ผ์šฐํŒ…์ด ๋งค๋ ฅ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • URL์— ๋Œ€ํ•œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ , HTTP ๋ฉ”์„œ๋“œ(GET, POST ๋“ฑ)๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

MySQL

ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๋Š” ์ฃผ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ '๋‚ ์งœ', '์ œ๋ชฉ', '๋‚ด์šฉ' ๋“ฑ์œผ๋กœ, ์ถ”ํ›„์— ํ™•์žฅ๋˜๊ธฐ๋ณด๋‹ค๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์กฐ๊ฐ€ ๋ช…ํ™•ํ•œ ์ •ํ˜• ๋ฐ์ดํ„ฐ๋ผ๊ณ  ํŒ๋‹จํ•˜์˜€๊ธฐ์— ์ ํ•ฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

โ—ผ๏ธŽ ํ”„๋กœ์ ํŠธ ์ด์Šˆ

๐Ÿ”ง ๋ฉ€์ฉกํ•˜๋˜ ํŽ˜์ด์ง€๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ๋งŒ ํ•˜๋ฉด ๊ฐ‘์ž๊ธฐ 404์—๋Ÿฌ? (feat.webpack)

๋ฌธ์ œ ์ƒํ™ฉ

'/diary' ๊ฒฝ๋กœ๋กœ ๋‹ค์ด์–ด๋ฆฌ๋ฅผ ํ™•์ธํ•˜๋Š” ๋„์ค‘ ๋‹ค์ด์–ด๋ฆฌ ํŽ˜์ด์ง€์—์„œ ์ฒ˜์Œ ๋ Œ๋”๋ง์€ ์ž˜ ๋˜๋‹ค๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ๋งŒ ํ•˜๋ฉด 404 ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค ๋„คํŠธ์›Œํฌ ํƒญ์—์„œ ํ™•์ธํ•ด ๋ณด๋‹ˆ, ์ฒ˜์Œ์—๋Š” '/diary/id'๋ผ๋Š” ์š”์ฒญ์„ ์ž˜ ๋ณด๋‚ด๋‹ค๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ๋งŒ ํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ '/diary/index.bundle.js'๋ผ๋Š” ๊ฒฝ๋กœ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

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

ํ•ด๋‹น ๋ฌธ์ œ๋Š” React Router๋กœ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ผ์šฐํŒ…์„ ๊ตฌํ˜„ํ•œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค.
ํŽ˜์ด์ง€ ์ „ํ™˜ ์—†์ด URL์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ํžˆ์Šคํ† ๋ฆฌ API๋ฅผ ํ™œ์šฉํ•˜์˜€์œผ๋‚˜, ์ƒˆ๋กœ๊ณ ์นจํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋Š”๋ฐ
์ด ๋ฌธ์ œ์˜ ๊ทผ๋ณธ ์›์ธ์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจํ•  ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„์— ํ˜„์žฌ URL์— ํ•ด๋‹นํ•˜๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
๋งŒ์•ฝ '/diary/:id' ๊ฐ™์€ ์„œ๋ธŒ ๊ฒฝ๋กœ์—์„œ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ํ•ด๋‹น ์„œ๋ธŒ ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์„œ๋ฒ„์— ์š”์ฒญํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ์„œ๋ฒ„์—๋Š” ๊ทธ๋Ÿฐ ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ํŒŒ์ผ์ด ์—†์–ด์„œ 404 ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์›นํŒฉ์˜ output.pubdivcPath ์˜ต์…˜์„ '/'๋กœ ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
ํ•ด๋‹น ์˜ต์…˜์€ ๋นŒ๋“œํ•œ ๊ฒฐ๊ณผ๋ฌผ์ด ์œ„์น˜ํ•  ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•˜๋Š” ์˜ต์…˜์ด๋ฉฐ pubdivcPath๋ฅผ '/'๋กœ ์„ค์ •ํ•˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ํ•ญ์ƒ ๋ฃจํŠธ ๊ฒฝ๋กœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•ด์„ํ•˜์—ฌ ๋ฃจํŠธ ๊ฒฝ๋กœ์—์„œ ๋กœ๋“œํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ ‡๊ฒŒ ๋œ๋‹ค๋ฉด ์„œ๋ธŒ ๊ฒฝ๋กœ์—์„œ๋„ ๋ฌธ์ œ ์—†์ด ๋นŒ๋“œํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ ๊ฐ™์€ ์›๋ฆฌ๋กœ ์›นํŒฉ์˜ devServer ์„ค์ •์—์„œ๋„ pubdivcPath๋ฅผ '/'๋กœ ์„ค์ •ํ•ด์•ผ ํ•˜๋ฉฐ. ํ•ญ์ƒ ๋ฃจํŠธ ๊ฒฝ๋กœ์—์„œ ๋นŒ๋“œํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ์ œ๊ณตํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ ๋ฐ ๋ฐฐ์šด์ 

์ด ๊ฒฝํ—˜์„ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ผ์šฐํŒ…์˜ ๋™์ž‘ ๋ฐฉ์‹๊ณผ ์›นํŒฉ ์„ค์ •์— ๋Œ€ํ•ด์„œ ์ข€ ๋” ๊นŠ์€ ์ดํ•ด๋ฅผ ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, ์›นํŒฉ์˜ output.pubdivcPath ์˜ต์…˜๊ณผ devServer ์„ค์ •์˜ ์ค‘์š”์„ฑ์„ ์ฒด๊ฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๐Ÿ”ง ReactQuill๋ฅผ ์ด์šฉํ•œ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ๊ธฐ๋Šฅ ๊ตฌํ˜„

๋ฌธ์ œ ์ƒํ™ฉ

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

  1. ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” UI๋ฅผ ์ œ๊ณต.
  2. ์„ ํƒํ•œ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์„œ๋ฒ„์— ์—…๋กœ๋“œ.
  3. ์—…๋กœ๋“œ๋œ ์ด๋ฏธ์ง€์˜ URL์„ ์—๋””ํ„ฐ์— ์‚ฝ์ž….
ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” UI๋Š” ์—๋””ํ„ฐ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋˜ React Quill์•ˆ์— ์žˆ๋Š” image ๋ฒ„ํŠผ์˜ Handler๋ฅผ ์ด์šฉํ•˜์˜€๊ณ 
์„ ํƒ๋œ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์„œ๋ฒ„์— ์—…๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์ ์ ˆํ•œ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด FormData ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
๋งˆ์ง€๋ง‰์œผ๋กœ, ์„œ๋ฒ„์—์„œ ๋ฐ›์€ ์‘๋‹ต์„ ํ†ตํ•ด ์ด๋ฏธ์ง€ URL์„ ์—๋””ํ„ฐ์— ์‚ฝ์ž…ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ž‘์—…์„ ์œ„ํ•ด React Quill์˜ API๋ฅผ ํ™œ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์ด๋ฏธ์ง€ URL์„ ์—๋””ํ„ฐ์˜ ํ˜„์žฌ ์ปค์„œ ์œ„์น˜์— ์‚ฝ์ž…ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
๊ทธ๋ ‡๊ฒŒ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ํ›„์—๋Š” ์ž๋™์œผ๋กœ ์—๋””ํ„ฐ์— ์ด๋ฏธ์ง€๊ฐ€ ์‚ฝ์ž…๋˜์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์œ„์น˜์— ์ด๋ฏธ์ง€๊ฐ€ ํฌํ•จ๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ ๋ฐ ๋ฐฐ์šด์ 

์ด๋Ÿฌํ•œ ๊ณ ๋ฏผ์„ ๋ฐ”ํƒ•์œผ๋กœ, ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ Redux์™€ ์ปค์Šคํ…€ ํ›…, ๊ทธ๋ฆฌ๊ณ  ์—๋””ํ„ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ Quill์„ ํ™œ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ์ง€๋ฅผ ์„ ํƒํ•˜๋ฉด ํ•ด๋‹น ์ด๋ฏธ์ง€๋ฅผ ์„œ๋ฒ„์— ์—…๋กœ๋“œํ•˜๊ณ , ์—…๋กœ๋“œ๋œ ์ด๋ฏธ์ง€์˜ URL์„ ์—๋””ํ„ฐ์— ์‚ฝ์ž…ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ฉด์„œ, React Quill ์—๋””ํ„ฐ์˜ ํ™•์žฅ์„ฑ, FormData ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•œ ํŒŒ์ผ ์—…๋กœ๋“œ ๋“ฑ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”ง Access Token๊ณผ Refresh Token์˜ ์ €์žฅ ๋ฐฉ์‹๊ณผ ๋ณด์•ˆ

๋ฌธ์ œ ์ƒํ™ฉ

ํšŒ์›์ œ๋„๋กœ ์šด์˜ํ•˜๊ธฐ ์œ„ํ•ด ๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•˜๋‹ค๋ณด๋‹ˆ ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐ์—๋Š” Access Token๊ณผ Refresh Token์„ ๋ชจ๋‘ ํด๋ผ์ด์–ธํŠธ์˜ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•˜๊ณ  ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.
์ด ๋ฐฉ์‹์€ ๊ฐ„๋‹จํ•˜๊ณ  ๊ตฌํ˜„์ด ์šฉ์ดํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์—ˆ์ง€๋งŒ, ๋ณด์•ˆ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
๋งŒ์•ฝ ์‚ฌ์šฉ์ž์˜ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ XSS(Cross-Site Scripting)๋“ฑ์˜ ๊ณต๊ฒฉ์„ ๋‹นํ•˜๋ฉด, ๊ณต๊ฒฉ์ž๋Š” ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ถฉ๋ถ„ํžˆ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ , ์ด๋กœ ์ธํ•ด ํ† ํฐ์ด ์œ ์ถœ๋  ์œ„ํ—˜์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

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

๊ทธ๋ž˜์„œ ์œ„ํ—˜์„ ์˜ˆ๋ฐฉํ•˜๊ณ ์ž ๋จผ์ € ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , sanitize-html ๋ชจ๋“ˆ์„ ์ด์šฉํ•ด์„œ ์‚ด๊ท ์ฒ˜๋ฆฌ๋ฅผ ํ•œ ๋’ค HTTPOnly ์ฟ ํ‚ค๋ฅผ ์ด์šฉํ•˜๋ฉฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•œ ์ ‘๊ทผ์„ ๋ฐฉ์ง€ํ•˜๋Š” ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ–ˆ์Šต๋‹ˆ๋‹ค.
ํ† ํฐ์˜ ๋ณด์•ˆ์„ฑ์„ ๋†’์ด๋Š” ๋™์‹œ์— ์‚ฌ์šฉ์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ์ƒˆ๋กœ์šด ์ €์žฅ ๋ฐฉ์‹์„ ๋ชจ์ƒ‰ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด, Access Token์€ ๋ฉ”๋ชจ๋ฆฌ์—, Refresh Token์€ HttpOnly ์ฟ ํ‚ค์— ์ €์žฅํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
Access Token์€ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์ดํŠธ๋ฅผ ์ด์šฉํ•˜๋Š” ๋™์•ˆ์—๋งŒ ํ•„์š”ํ•˜๋ฏ€๋กœ, ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์ ํ•ฉํ•˜๋‹ค๊ณ  ํŒ๋‹จํ•˜์˜€์Šต๋‹ˆ๋‹ค.
๋ฐ˜๋ฉด, Refresh Token์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•˜๋ฏ€๋กœ, HttpOnly ์ฟ ํ‚ค์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆํ•˜๋‹ค๊ณ  ํŒ๋‹จํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ ๋ฐ ๋ฐฐ์šด์ 

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

๐Ÿ”ง Access Token ๋งŒ๋ฃŒ์— ๋Œ€์‘ํ•˜๋Š” Refresh Token ํ™œ์šฉ๊ณผ ์š”์ฒญ ์žฌ์‹œ๋„ ๋ฐฉ๋ฒ•

๋ฌธ์ œ ์ƒํ™ฉ

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

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

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, Access Token์ด ๋งŒ๋ฃŒ๋˜์—ˆ์„ ๋•Œ Refresh Token์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด Access Token์„ ๋ฐœ๊ธ‰๋ฐ›๋Š” ๋ฐฉ์‹์„ ๋„์ž…ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด ์„œ๋ฒ„์—์„œ๋Š” ์‚ฌ์šฉ์ž์˜ Refresh Token์„ ๊ฒ€์ฆํ•˜๊ณ , ์œ ํšจํ•˜๋‹ค๋ฉด ์ƒˆ๋กœ์šด Access Token์„ ๋ฐœ๊ธ‰ํ•˜๋Š” API๋ฅผ ์ œ๊ณตํ•˜์˜€๊ณ 
ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ์š”์ฒญ์ด๋‚˜ ์‘๋‹ต์„ ๊ฐ€๋กœ์ฑ„์–ด ์›ํ•˜๋Š” ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” axios์˜ ์ธํ„ฐ์…‰ํ„ฐ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜์—ฌ
API ์š”์ฒญ ์‹œ 401 ์—๋Ÿฌ๋ฅผ ๋ฐ›์œผ๋ฉด, ์ด API๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒˆ๋กœ์šด Access Token์„ ๋ฐ›์•„์™€ ๋‹ค์‹œ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ ๋ฐ ๋ฐฐ์šด์ 

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