Spring Security Document - dev-team-projects/DeliTalk GitHub Wiki

์ž‘์„ฑ์ž : ์ž„์„ฑ์ค€


Spring Security

  • ์Šคํ”„๋ง ๊ธฐ๋ฐ˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ณด์•ˆ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.
    • โžก๏ธ ํŠนํžˆ ์ธ์ฆ(Authentication) ๊ณผ ์ธ๊ฐ€(Authorization) ๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ํ™•์ธํ•˜๊ณ  ํ•ด๋‹น ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ์ง€ ๊ด€๋ฆฌํ•˜๋Š” ์—ญํ• ์„ํ•ฉ๋‹ˆ๋‹ค.

์ธ์ฆ(Authentication)

  • ์‚ฌ์šฉ์ž๊ฐ€ ์ฃผ์žฅํ•˜๋Š” ์‹ ์›์„ ํ™•์ธํ•˜๋Š” ์ ˆ์ฐจ์ž…๋‹ˆ๋‹ค.
    • ์‹œ์Šคํ…œ์ด๋‚˜ ์„œ๋น„์Šค์— ์ ‘๊ทผํ•˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ ๋ณธ์ธ์ธ์ง€ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์ด๋ผ๊ณ ๋„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฌ์ธ๊ฐ€๋ฅผ ํ™•์ธํ•˜๋Š” ์ ˆ์ฐจ

์ธ์ฆ์˜ ์ค‘์š”์„ฑ

  • ๋ฌด๋‹จ ์ ‘๊ทผ์„ ๋ฐฉ์ง€ํ•˜์—ฌ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•ฉ๋‹ˆ๋‹ค.
    • โžก๏ธ ๋ณด์•ˆ๊ฐ•ํ™”
  • ํ—ˆ๊ฐ€๋˜์ง€ ์•Š๋Š” ์ ‘๊ทผ์œผ๋กœ ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•ฉ๋‹ˆ๋‹ค.
    • โžก๏ธ ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ
  • ์—„๊ฒฉํ•œ ์•ก์„ธ์Šค ์ œ์–ด ์ •์ฑ…๊ณผ ์‚ฌ์šฉ์ž ํ™œ๋™ ์ถ”์ ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
    • โžก๏ธ ๊ทœ์ • ์ค€์ˆ˜

์ธ๊ฐ€(Authorization)

  • ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž๋‚˜ ์‹œ์Šคํ…œ์ด ํŠน์ • ๋ฆฌ์†Œ์Šค๋‚˜ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.

์ธ์ฆ๋œ ์‚ฌ์šฉ์ž๋‚˜ ์‹œ์Šคํ…œ์ด ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ณผ์ •

์ธ๊ฐ€์˜ ์ค‘์š”์„ฑ

  • ๋ณด์•ˆ ์œ ์ง€
  • ์ค‘์š”ํ•œ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ๋ฌด๋‹จ ์ ‘๊ทผ ๋ฐฉ์ง€

์ธ์ฆ๊ณผ ์ธ๊ฐ€์˜ ์ฐจ์ด์ 

  • ์ธ์ฆ์€ ์‹ ๋ถ„ ํ™•์ธ ๊ณผ์ •์ด๊ณ  ์ธ๊ฐ€๋Š” ์‹ ๋ถ„์ด ํ™•์ธ๋œ ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋А ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ์ง€ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.

Spring Security์˜ ๋ณด์•ˆ ๊ธฐ๋Šฅ

  • CSRF ๋ฐฉ์ง€
  • ์„ธ์…˜๊ด€๋ฆฌ ๋“ฑ

Spring Security๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ

  • JSP/Servlet ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” HttpSession์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๋งŒ ์ƒํ’ˆ ๋“ฑ๋ก, ์ƒํ’ˆ ์‚ญ์ œ ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ƒํ’ˆ ์‚ญ์ œ ์‹œ์—๋Š” ์„ธ์…˜ ์ •๋ณด๋ฅผ ํ™•์ธํ•˜์—ฌ ํ•ด๋‹น ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ์ƒํ’ˆ์„ ์‚ญ์ œํ•  ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ๊ฒ€์ฆํ•˜๋„๋ก ์ฒ˜๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ์ด๋ฅผ ์œ„ํ•ด AccessFilter ๋ฅผ ๊ณต์šฉ ํด๋ž˜์Šค๋กœ ์ž‘์„ฑํ•˜์—ฌ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€์™€ ์ผ๋ถ€ ๊ถŒํ•œ ๊ฒ€์ฆ ๋กœ์ง์„ ์ค‘์•™์—์„œ ๊ด€๋ฆฌํ•˜๊ณ  ๋ฐ˜๋ณต์ ์ธ ์ฝ”๋“œ๋ฅผ ์ค„์˜€์Šต๋‹ˆ๋‹ค.

  • ํ•˜์ง€๋งŒ AccessFilter๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ URL ๋‹จ์œ„ ์ ‘๊ทผ ์ œ์–ด์—๋งŒ ๊ฐ€๋Šฅํ•˜์—ฌ ๋ฉ”์„œ๋“œ ๋‹จ์œ„์˜ ์„ธ๋ฐ€ํ•œ ๊ถŒํ•œ ๊ด€๋ฆฌ๋‚˜ ์—ญํ•  ๊ธฐ๋ฐ˜ ์ธ๊ฐ€ ๋“ฑ ๊ณ ๊ธ‰ ๋ณด์•ˆ ์ •์ฑ…์„ ์ ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ํ•œ๊ณ„๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  • ๋˜ํ•œ JWT๋‚˜ OAuth2 ๊ฐ™์€ ๋‹ค์–‘ํ•œ ์ธ์ฆ ๋ฐฉ์‹์„ ์ ์šฉํ•˜๊ฑฐ๋‚˜ CSRF ๋ณดํ˜ธ, ์„ธ์…˜ ๊ณ ์ • ๋ฐฉ์ง€ ๋“ฑ ์ถ”๊ฐ€์ ์ธ ๋ณด์•ˆ ์ •์ฑ…์„ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ ์ง€๋ณด์ˆ˜์™€ ํ™•์žฅ์„ฑ ์ธก๋ฉด์—์„œ ๋งŽ์€ ์–ด๋ ค์›€์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

Spring Security๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ 

  • ์ธ์ฆ/์ธ๊ฐ€๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ•ด์ฃผ๋ฏ€๋กœ ๋ณด์•ˆ์„ฑ์„ ๋†’์—ฌ์ค๋‹ˆ๋‹ค.
  • ๋‹ค์–‘ํ•œ ๋ณด์•ˆ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์ฃผ๋ฏ€๋กœ ๋”ฐ๋กœ ๋ณด์•ˆ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค.
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํŠน์„ฑ์— ๋งž๋„๋ก ์œ ์—ฐํ•˜๊ฒŒ ๋ณด์•ˆ ์„ค์ •์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Spring Security์˜ ๋™์ž‘ ์›๋ฆฌ

๋จผ์ € Servlet Filter์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค..

Servlet Filter

  • ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์„œ Servlet์ด ์ˆ˜ํ–‰๋˜๊ธฐ ์ „ํ›„์— ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜ ์š”์ฒญ์„ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ์ผ๋ฐ˜์ ์œผ๋กœ ํ•œ ๊ฐœ์˜ ํ•„ํ„ฐ๋‹น ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ•„ํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด ํ•„ํ„ฐ ์ฒด์ธ์„ ํ˜•์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Servlet Filter ๊ตฌ์กฐ

  • Spring Security๋Š” Security์™€ ๊ด€๋ จ๋œ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ๋“ค์„ ํ•„ํ„ฐ ์ฒด์ธ์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค๋ฉด ์ธ์ฆ๋˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • URL์„ ์š”์ณฅํ–ˆ์„ ๋•Œ ๋กœ๊ทธ์ธ ํ™”๋ฉด์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด Security Filter ์ค‘ ํ•˜๋‚˜์— ์˜ํ•ด์„œ ์ฒ˜๋ฆฌ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Spring Security์—์„œ ์‚ฌ์šฉํ•˜๋Š” Filter

Filter Feature
SecurityContextPersistenceFilter SecurityContextRepository์—์„œ SecurityContext ๊ฐ์ฒด๋ฅผ ๋กœ๋”ฉํ•˜์—ฌ SecurityContextHolder์— ์ €์žฅํ•˜๊ณ  ์š”์ฒญ ์ฒ˜๋ฆฌ๊ฐ€ ๋๋‚˜๋ฉด ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
LogoutFilter ์ง€์ •ํ•œ ๊ฒฝ๋กœ์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ๋กœ๊ทธ์•„์›ƒํ•˜๊ณ  ์ง€์ •ํ•œ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ํ•„ํ„ฐ๋“ค์„ ์ง„ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
UsernamePasswordAuthenticationFilter ๋กœ๊ทธ์ธ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ID/PW ๊ธฐ๋ฐ˜์˜ ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์„ฑ๊ณต ์‹œ ์ง€์ •ํ•œ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ณ  ์‹คํŒจ ์‹œ ๋กœ๊ทธ์ธ ํ™”๋ฉด์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
DefaultLoginPageGeneratingFilter ๋กœ๊ทธ์ธ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ๋กœ๊ทธ์ธ ํ™”๋ฉด์„ ์ถœ๋ ฅํ•˜๊ณ  ์ดํ›„ ํ•„ํ„ฐ๋ฅผ ์ง„ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
AnonymousAuthenticationFilter ์ด ํ•„ํ„ฐ๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ ๊นŒ์ง€ ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ฆ์„ ๋ฐ›์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด ์ž„์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•ด๋‹นํ•˜๋Š” Authentication ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ SecurityContext์— ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
์ƒ์„ฑ๋œ Authentication์˜ ์•„์ด๋””๋Š” anonymousUser์ด๊ณ  ๊ถŒํ•œ์€ ROLE_ANONYMOUS์ด๋ฉฐ ์ธ์ฆ๋˜์ง€ ์•Š์€ ์ƒํƒœ์˜ ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
SessionManagementFilter ์„ธ์…˜ ํƒ€์ž„์•„์›ƒ, ๋™์‹œ ์ ‘๊ทผ ์ œ์–ด, ์„ธ์…˜ ๊ณ ์ • ๊ณต๊ฒฉ ๋“ฑ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
ExceptionTranslationFilter FilterSecurityInterceptor์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋ฅผ ๋งž๋Š” ์‘๋‹ต์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 403 ์ƒํƒœ์ฝ”๋“œ๋ฅผ ์‘๋‹ตํ•˜๊ฑฐ๋‚˜ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
FilterSecurityInterceptor ํ˜„์žฌ ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ •ํ•œ ๊ฒฝ๋กœ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ถŒํ•œ์ด ์žˆ์œผ๋ฉด ๋ณด์•ˆ ํ•„ํ„ฐ๋ฅผ ํ†ต๊ณผ์‹œ์ผœ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ณ  ๊ถŒํ•œ์ด ์—†์œผ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.
  • ๊ฐ ํ•„ํ„ฐ๋Š” Security ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๊ธฐ๋Šฅ์œผ๋กœ ์œ„์—์„œ๋ถ€ํ„ฐ ์•„๋ž˜๋กœ ์ˆœ์ฐจ์ ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

Spring Security์˜ ๋™์ž‘ ์›๋ฆฌ ์ดํ•ดํ•˜๊ธฐ

  • Spring Security๋Š” Security ํ•„ํ„ฐ๋“ค์˜ ์ƒํ˜ธ์ž‘์šฉ์— ์˜ํ•ด ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
  • Spring Security์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ํ•„ํ„ฐ๋Š” UsernamePasswordAuthenticationFilter ์ž…๋‹ˆ๋‹ค.
    • ์ด ํ•„ํ„ฐ๊ฐ€ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ธ์ฆ ์ •๋ณด๋ฅผ ์ด์šฉํ•ด์„œ ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
  • ๋‘๋ฒˆ์งธ๋กœ ์ค‘์š”ํ•œ ๊ฐ์ฒด๋Š” FilterSecurityInterceptor์ž…๋‹ˆ๋‹ค.
    • ์ด ๊ฐ์ฒด๋Š” ์ธ์ฆ์— ์„ฑ๊ณตํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€๋ฅผ ๊ฒ€์ฆํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

Spring Security์˜ ๊ตฌ์กฐ

Spring Security ๊ตฌ์กฐ

  1. ์‚ฌ์šฉ์ž๊ฐ€ ๋ฆฌ์†Œ์Šค ์š”์ฒญ ์‹œ ์ธ์ฆ ๊ด€๋ฆฌ ํ•„ํ„ฐ๊ฐ€ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ•๋‹ˆ๋‹ค.
  2. ์ธ์ฆ ๊ด€๋ฆฌ ํ•„ํ„ฐ๋Š” ์ธ์ฆ ์ฒ˜๋ฆฌ์™€ ๊ด€๋ จ๋œ ํ•„ํ„ฐ๋“ค์„ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ฆ ์ ˆ์ฐจ๋ฅผ ํ†ตํ•ด ์ธ์ฆ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ํŒŒ์ผ์ด๋‚˜ DB์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ฝ์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ธ์ฆ ์ •๋ณด๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
    • ์ธ์ฆ ์‹คํŒจ ์‹œ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‹ค์‹œ ์ธ์ฆ ์ •๋ณด๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
    • ์ธ์ฆ ์„ฑ๊ณต ์‹œ ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญํ•œ ๋ฆฌ์†Œ์Šค๋กœ ์š”์ฒญ์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  3. ์ธ์ฆ ์„ฑ๊ณต ํ›„ ์š”์ฒญํ•œ ๋ฆฌ์†Œ์Šค๋กœ ์š”์ฒญ์„ ์ „๋‹ฌํ•  ๋•Œ ๊ถŒํ•œ ๊ด€๋ฆฌ ํ•„ํ„ฐ๊ฐ€ ๋‹ค์‹œ ์š”์ฒญ์„ ๊ฐ€๋กœ ์ฑ„์„œ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ถŒํ•œ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
    • ๊ถŒํ•œ์„ ๊ฒ€์ฆํ•˜๊ธฐ ์œ„ํ•ด ๊ด€๋ จ๋œ ํ•„ํ„ฐ๋“ค์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๊ถŒํ•œ ๊ด€๋ฆฌ ํ•„ํ„ฐ๋Š” ๋ฆฌ์†Œ์Šค๋ณ„ ๊ถŒํ•œ ๋ชฉ๋ก์„ ์ฐธ์กฐํ•˜์—ฌ ์ ‘๊ทผ ๊ถŒํ•œ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฒ€์ฆ ์‹คํŒจ ์‹œ ๊ถŒํ•œ ์—†์Œ ํŽ˜์ด์ง€๋ฅผ ์ „์†กํ•˜๊ฑฐ๋‚˜ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.
โš ๏ธ **GitHub.com Fallback** โš ๏ธ