Skip to content

๐Ÿš€[๊ธฐ๋Šฅ๊ฐœ์„ ][๊ด€๋ฆฌ์ž] ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€ ๋กœ๊ทธ์ธ ๋ฐฉ์‹ ๊ฐœ์„  (URL ํ† ํฐ ํ๊ธฐ)ย #939

Description

@Cassiiopeia

๐Ÿ“ ํ˜„์žฌ ๋ฌธ์ œ์ 

ํ˜„์žฌ ๊ด€๋ฆฌ์ž ์›น ํ™”๋ฉด์˜ ์ธ์ฆ/๋กœ๊ทธ์ธ ๋ฐฉ์‹์ด ์ž˜๋ชป ์„ค๊ณ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋™์ž‘ ํ๋ฆ„

  • ๋กœ๊ทธ์ธ ์„ฑ๊ณต ํ›„ JWT accessToken์„ ๋ธŒ๋ผ์šฐ์ € localStorage์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค URL ์ฟผ๋ฆฌํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ?accessToken=xxx๋ฅผ ์ง์ ‘ ๋ถ™์—ฌ์„œ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„๋Š” ๊ฐ /admin/** ๋งคํ•‘์—์„œ ์ด ์ฟผ๋ฆฌํŒŒ๋ผ๋ฏธํ„ฐ ํ† ํฐ์„ jwtUtil.validateToken()์œผ๋กœ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ จ ํŒŒ์ผ

  • SM-Web/src/main/java/com/balsamic/sejongmalsami/web/controller/view/AdminPageController.java
    • /admin/question, /admin/document, /admin/dashboard, /admin/member, /admin/subject, /admin/notice, /admin/notification ๋“ฑ ๊ฑฐ์˜ ๋ชจ๋“  /admin/** GET ๋งคํ•‘์ด @RequestParam String accessToken์„ ๋ฐ›์•„ jwtUtil.validateToken(accessToken)์œผ๋กœ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
    • ์ผ๋ถ€ ๋งคํ•‘์€ log.info(accessToken) ํ˜•ํƒœ๋กœ ํ† ํฐ์„ ๋กœ๊ทธ์— ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅํ•˜๊ธฐ๊นŒ์ง€ ํ•ฉ๋‹ˆ๋‹ค.
  • SM-Web/src/main/resources/static/js/auth.js
    • navigate()๊ฐ€ localStorage์˜ ํ† ํฐ์„ ์ฝ์–ด ์ด๋™ URL ๋์— ?accessToken=...๋ฅผ ๋ถ™์ž…๋‹ˆ๋‹ค.
    • ํŽ˜์ด์ง€ ์ง„์ž… ์‹œ checkAccessToken()์œผ๋กœ ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ๋งŒ ํ† ํฐ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • SM-Web/src/main/resources/templates/login.html

์™œ ์ž˜๋ชป๋˜์—ˆ๋Š”๊ฐ€

  • ๋ณด์•ˆ ์ทจ์•ฝ โ€” accessToken์ด URL ์ฟผ๋ฆฌ์ŠคํŠธ๋ง์— ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ํžˆ์Šคํ† ๋ฆฌ, ์„œ๋ฒ„ access log, Referer ํ—ค๋”์— ํ† ํฐ์ด ํ‰๋ฌธ์œผ๋กœ ๋‚จ์•„ ํ† ํฐ์ด ์œ ์ถœ๋  ์œ„ํ—˜์ด ํฝ๋‹ˆ๋‹ค. (์‹ค์ œ๋กœ ์ปจํŠธ๋กค๋Ÿฌ ์ผ๋ถ€๋Š” ํ† ํฐ์„ ๋กœ๊ทธ๋กœ ๋‚จ๊ธฐ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.)
  • UX ๋ถˆ์•ˆ์ • โ€” ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค ํ† ํฐ์„ URL์— ์ˆ˜๋™์œผ๋กœ ๋ถ™์—ฌ์•ผ ํ•˜๋ฏ€๋กœ ๋„ค๋น„๊ฒŒ์ด์…˜์ด ์‰ฝ๊ฒŒ ๊นจ์ง€๊ณ  ์‚ฌ์šฉ ๊ฒฝํ—˜์ด ๋‚˜์ฉ๋‹ˆ๋‹ค.
  • ํ‘œ์ค€์—์„œ ๋ฒ—์–ด๋‚จ โ€” ์ผ๋ฐ˜์ ์ธ ๊ด€๋ฆฌ์ž ์ธ์ฆ(Spring Security ์„ธ์…˜ ๊ธฐ๋ฐ˜ ํผ๋กœ๊ทธ์ธ + ์ฟ ํ‚ค, ๋˜๋Š” HttpOnly ์ฟ ํ‚ค ๊ธฐ๋ฐ˜ JWT)๊ณผ ๋™๋–จ์–ด์ง„ ๋น„ํ‘œ์ค€ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

๐Ÿ› ๏ธ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ / ์ œ์•ˆ ๊ธฐ๋Šฅ

  • URL ์ฟผ๋ฆฌํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ํ† ํฐ์„ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์„ ํ๊ธฐํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜์˜ ํ‘œ์ค€ ๋ฐฉ์‹์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • (๊ถŒ์žฅ) Spring Security ์„ธ์…˜ ๊ธฐ๋ฐ˜ ํผ๋กœ๊ทธ์ธ โ€” /admin/** ๊ฒฝ๋กœ ์ „์šฉ SecurityFilterChain์„ ๋‘๊ณ  ์„ธ์…˜ + ์ฟ ํ‚ค(JSESSIONID)๋กœ ์ธ์ฆ์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • ๋˜๋Š” HttpOnly ์ฟ ํ‚ค ๊ธฐ๋ฐ˜ JWT โ€” ํ† ํฐ์„ JS์—์„œ ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅํ•œ HttpOnly ์ฟ ํ‚ค์— ๋‹ด์•„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ์ „ํ™˜ ํ›„์—๋Š” ์ปจํŠธ๋กค๋Ÿฌ์—์„œ @RequestParam String accessToken ์ˆ˜์‹ ยท๊ฒ€์ฆ ๋กœ์ง๊ณผ auth.js์˜ URL ํ† ํฐ ๋ถ€์ฐฉ ๋กœ์ง์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ  ๋ ˆํผ๋Ÿฐ์Šค

  • ๊ฐ™์€ ์ž‘์„ฑ์ž์˜ passQL ํ”„๋กœ์ ํŠธ AdminSecurityConfig๊ฐ€ ์ด๋ฏธ /admin/** ๊ฒฝ๋กœ์— ๋Œ€ํ•ด Spring Security ์„ธ์…˜ ํผ๋กœ๊ทธ์ธ์„ ์ ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
    • /admin/**์—๋งŒ ์ ์šฉ๋˜๋Š” ๋ณ„๋„ SecurityFilterChain(@Order(1))์„ ๋‘๊ณ , JWT API chain๊ณผ ์™„์ „ํžˆ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • formLogin(loginPage/loginProcessingUrl/defaultSuccessUrl), logout(deleteCookies("JSESSIONID")), SessionCreationPolicy.IF_REQUIRED, userDetailsService + BCryptPasswordEncoder ๊ตฌ์„ฑ์„ ๊ทธ๋Œ€๋กœ ์ฐธ๊ณ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โš™๏ธ ์ž‘์—… ๋‚ด์šฉ

  • /admin/** ์ „์šฉ Security ์„ค์ •(์„ธ์…˜ ํผ๋กœ๊ทธ์ธ ๋˜๋Š” HttpOnly ์ฟ ํ‚ค JWT) ๋„์ž…
  • AdminPageController์˜ ๋ชจ๋“  /admin/** ๋งคํ•‘์—์„œ accessToken ์ฟผ๋ฆฌํŒŒ๋ผ๋ฏธํ„ฐ ์ˆ˜์‹ ยท๊ฒ€์ฆ ๋กœ์ง ์ œ๊ฑฐ (ํ† ํฐ ๋กœ๊ทธ ์ถœ๋ ฅ ์ œ๊ฑฐ ํฌํ•จ)
  • auth.js์˜ URL ํ† ํฐ ๋ถ€์ฐฉยทํด๋ผ์ด์–ธํŠธ ํ† ํฐ ์ฒดํฌ ๋กœ์ง ์ •๋ฆฌ
  • ๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ ํ๋ฆ„(login.html, /logout) ํ‘œ์ค€ ๋ฐฉ์‹์— ๋งž์ถฐ ์žฌ์ •๋น„

โš ๏ธ ๋ณธ ์ด์Šˆ๋Š” "๊ด€๋ฆฌ์ž ํ™”๋ฉด UI๋ฅผ daisyUI๋กœ ์ „๋ฉด ๊ต์ฒดํ•˜๋Š” ์ž‘์—…"๊ณผ๋Š” ๋ณ„๊ฐœ์˜ ํ›„์† ๊ฐœ์„  ๊ณผ์ œ์ž…๋‹ˆ๋‹ค. UI ๊ต์ฒด ์ž‘์—…์—์„œ๋Š” ์ธ์ฆ์„ ์ผ๋‹จ ๊ธฐ์กด ๋ฐฉ์‹ ๊ทธ๋Œ€๋กœ ๋‘๊ณ , ๊ทธ ์ดํ›„ ๋ณธ ์ด์Šˆ์—์„œ ์ธ์ฆ์„ ํ‘œ์ค€ ๋ฐฉ์‹์œผ๋กœ ์ œ๋Œ€๋กœ ๊ณ ์น˜๊ธฐ ์œ„ํ•œ ํŠธ๋ž˜ํ‚น์šฉ ์ด์Šˆ์ž…๋‹ˆ๋‹ค.

๐Ÿ™‹โ€โ™‚๏ธ ๋‹ด๋‹น์ž

  • ๋ฐฑ์—”๋“œ: ์ด๋ฆ„
  • ํ”„๋ก ํŠธ์—”๋“œ: ์ด๋ฆ„
  • ๋””์ž์ธ: ์ด๋ฆ„

Metadata

Metadata

Assignees

No one assigned

    Labels

    ์ž‘์—…์ „์ž‘์—… ์‹œ์ž‘ ์ „ ์ค€๋น„ ์ƒํƒœ

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions