์ด์ง€๋ฏผ์˜ ๊ฐœ๋ฐœ ๋…ธํŠธ

๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์„ ๊ณต๋ถ€ํ•˜๋ฉฐ Java์™€ Spring์„ ์ค‘์‹ฌ์œผ๋กœ ํ•™์Šต ๊ธฐ๋ก์„ ์ •๋ฆฌํ•˜๋Š” ๊ณต๊ฐ„์ž…๋‹ˆ๋‹ค.

๐Ÿ”ฅ ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„/๐Ÿ“Œ ๊ณผ์ œ

[๋‚ด์ผ๋ฐฐ์›€์บ ํ”„ Spring 3๊ธฐ] CH 3 ์‹ฌํ™” Spring ์ฝ”๋“œ ๊ฐœ์„  ๊ณผ์ œ - ๋„์ „ ๊ธฐ๋Šฅ

jiiimni 2026. 3. 10. 12:52

Spring ์‹ฌํ™” ๋„์ „ ๊ธฐ๋Šฅ (Lv5 ~ Lv7)

์ด๋ฒˆ ๋‹จ๊ณ„์—์„œ๋Š” ๊ธฐ์กด ํ•„์ˆ˜ ๊ธฐ๋Šฅ ์œ„์— ๋‹ค์Œ ์ž‘์—…์„ ์ง„ํ–‰ํ–ˆ๋‹ค.

  1. JWT ์ธ์ฆ ๊ตฌ์กฐ ๋ฆฌํŒฉํ† ๋ง
  2. ์ธ์ฆ ์ฑ…์ž„ ๋ถ„๋ฆฌ
  3. ArgumentResolver ํ™œ์šฉ
  4. ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ
  5. ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ •

๋‹จ์ˆœํžˆ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ฝ”๋“œ ๊ตฌ์กฐ ๊ฐœ์„ ๊ณผ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์— ์ง‘์ค‘ํ–ˆ๋‹ค.


Lv5 JWT ์ธ์ฆ ๊ตฌ์กฐ ๊ฐœ์„ 

๋ฌธ์ œ ์ƒํ™ฉ

JWT ์ธ์ฆ ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ๋•Œ ์ฒ˜์Œ์—๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๋กœ์ง์ด JwtFilter์— ์ง‘์ค‘๋˜์–ด ์žˆ์—ˆ๋‹ค.

๊ธฐ์กด JwtFilter๋Š” ๋‹ค์Œ ์—ญํ• ์„ ๋ชจ๋‘ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

JwtFilter

  • ํ† ํฐ ๊ฒ€์ฆ
  • Claims ์ถ”์ถœ
  • ์‚ฌ์šฉ์ž ์ •๋ณด request ์ €์žฅ
  • ๊ด€๋ฆฌ์ž ๊ถŒํ•œ ๊ฒ€์‚ฌ

์ฆ‰ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ์—ญํ• ์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋‹ค.

์ด ๊ตฌ์กฐ๋Š” ๋‹ค์Œ ๋ฌธ์ œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

  1. ํด๋ž˜์Šค์˜ ์ฑ…์ž„์ด ๋„ˆ๋ฌด ๋งŽ์•„์ง
  2. ํ…Œ์ŠคํŠธ๊ฐ€ ์–ด๋ ค์›Œ์ง
  3. ์ฝ”๋“œ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์ง

์ด ๋ฌธ์ œ๋Š” ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„ ์›์น™ ์ค‘ ํ•˜๋‚˜์ธ SRP(Single Responsibility Principle) ๋ฅผ ์œ„๋ฐ˜ํ•˜๋Š” ๊ตฌ์กฐ์˜€๋‹ค.

SRP๋Š” ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋Š” ํ•˜๋‚˜์˜ ์ฑ…์ž„๋งŒ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค๋Š” ์›์น™์ด๋‹ค.


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

JWT ์ธ์ฆ ๊ด€๋ จ ๋กœ์ง์„ JwtAuthHelper ํด๋ž˜์Šค๋กœ ๋ถ„๋ฆฌํ•˜์˜€๋‹ค.

๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.

๊ธฐ์กด ๊ตฌ์กฐ

JwtFilter
 -> validate token
 -> extract claims
 -> set request attribute
 -> check admin role

๊ฐœ์„  ๊ตฌ์กฐ

JwtFilter
 -> JwtAuthHelper

JwtAuthHelper

validateAndExtractClaims()
setUserAttributes()
validateAdminAccess()

์ด๋ ‡๊ฒŒ ์ธ์ฆ ๊ด€๋ จ ๋กœ์ง์„ Helper ํด๋ž˜์Šค๋กœ ์ด๋™์‹œ์ผฐ๋‹ค.


JwtAuthHelper

ํ† ํฐ ๊ฒ€์ฆ๊ณผ Claims ์ถ”์ถœ์„ ๋‹ด๋‹นํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

public Claims validateAndExtractClaims(HttpServletRequest request) {
    String bearerJwt = request.getHeader("Authorization");

    if (bearerJwt == null) {
        throw new IllegalArgumentException("์ธ์ฆ ํ—ค๋”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.");
    }

    String jwt = jwtUtil.substringToken(bearerJwt);
    Claims claims = jwtUtil.extractClaims(jwt);

    if (claims == null) {
        throw new IllegalArgumentException("์œ ํšจํ•˜์ง€ ์•Š์€ ํ† ํฐ์ž…๋‹ˆ๋‹ค.");
    }

    return claims;
}

์ด ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ ์ˆœ์„œ๋กœ ๋™์ž‘ํ•œ๋‹ค.

Authorization Header ํ™•์ธ

  • Bearer ํ† ํฐ ๋ถ„๋ฆฌ
  • JWT Claims ์ถ”์ถœ

JWT์—์„œ Claims๋Š” ํ† ํฐ์— ๋‹ด๊ธด ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด

userId
email
userRole

๊ฐ™์€ ์ •๋ณด๋“ค์ด Claims์— ํฌํ•จ๋œ๋‹ค.


์‚ฌ์šฉ์ž ์ •๋ณด request ์ €์žฅ

JWT์—์„œ ์ถ”์ถœํ•œ ์ •๋ณด๋ฅผ request attribute๋กœ ์ €์žฅํ•˜์˜€๋‹ค.

public void setUserAttributes(HttpServletRequest request, Claims claims) {
    request.setAttribute("userId", Long.parseLong(claims.getSubject()));
    request.setAttribute("email", claims.get("email"));
    request.setAttribute("userRole", claims.get("userRole"));
}

์ด๋ ‡๊ฒŒ ์ €์žฅํ•œ ์ด์œ ๋Š” ์ดํ›„ ๋‹จ๊ณ„์—์„œ ๋‹ค์Œ ๊ตฌ์กฐ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

JwtFilter
 -> request attribute ์ €์žฅ
 -> ArgumentResolver
 -> Controller

์ฆ‰ Controller์—์„œ๋Š” request๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  AuthUser ๊ฐ์ฒด๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.


๊ด€๋ฆฌ์ž ๊ถŒํ•œ ๊ฒ€์‚ฌ

๊ด€๋ฆฌ์ž API ์ ‘๊ทผ ์‹œ ๊ถŒํ•œ์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋กœ์ง์ด๋‹ค.

public void validateAdminAccess(String url, Claims claims) {
    UserRole userRole = UserRole.valueOf(claims.get("userRole", String.class));

    if (url.startsWith("/admin") && !UserRole.ADMIN.equals(userRole)) {
        throw new IllegalArgumentException("์ ‘๊ทผ ๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค.");
    }
}

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ํฌ์ธํŠธ๋Š” ๋‹ค์Œ์ด๋‹ค.

url.startsWith("/admin")

์ฆ‰ ๊ด€๋ฆฌ์ž API ๊ฒฝ๋กœ๋Š”

/admin/comments
/admin/users

๊ฐ™์ด ์‹œ์ž‘ํ•˜๋„๋ก ์„ค๊ณ„๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—
์ด ๊ฒฝ๋กœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ถŒํ•œ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค.


๊ตฌ์กฐ ๊ฐœ์„  ๊ฒฐ๊ณผ

๊ธฐ์กด ๊ตฌ์กฐ

JwtFilter
 -> ์ธ์ฆ
 -> ์ธ๊ฐ€
 -> ์‚ฌ์šฉ์ž ์ •๋ณด ์ฒ˜๋ฆฌ
 -> ํ† ํฐ ์ฒ˜๋ฆฌ

๊ฐœ์„  ๊ตฌ์กฐ

JwtFilter
 -> JwtAuthHelper

์ฆ‰

Filter -> ์š”์ฒญ ํ๋ฆ„ ์ œ์–ด
Helper -> ์ธ์ฆ ๋กœ์ง ์ฒ˜๋ฆฌ

๋กœ ์—ญํ• ์„ ๋ถ„๋ฆฌํ•˜์˜€๋‹ค.


Lv6 ์ฝ”๋“œ ๊ตฌ์กฐ ๊ฐœ์„  ๋ฐ ๋ฆฌํŒฉํ† ๋ง

๋ฌธ์ œ ์ธ์‹

๊ธฐ๋Šฅ ๊ตฌํ˜„์ด ์™„๋ฃŒ๋œ ํ›„ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•˜๋ฉด์„œ ๋‹ค์Œ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ๋‹ค.

  1. ์ธ์ฆ ์ •๋ณด๋ฅผ Controller์—์„œ ์ง์ ‘ ๊บผ๋‚ด๋Š” ์ฝ”๋“œ ์กด์žฌ
  2. request attribute ์ ‘๊ทผ ์ฝ”๋“œ ๋ฐ˜๋ณต
  3. ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์ด ์–ด๋ ค์šด ๊ตฌ์กฐ

์˜ˆ๋ฅผ ๋“ค์–ด ๊ธฐ์กด ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์•˜๋‹ค.

Long userId = (Long) request.getAttribute("userId");

์ด ๋ฐฉ์‹์€ ๋‹ค์Œ ๋ฌธ์ œ๋ฅผ ๊ฐ€์ง„๋‹ค.

  1. Controller๊ฐ€ HttpServletRequest์— ์˜์กด
  2. ์ธ์ฆ ์ •๋ณด ์ฒ˜๋ฆฌ ์ฝ”๋“œ๊ฐ€ ๋ฐ˜๋ณต๋จ
  3. ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์ด ์–ด๋ ค์›€

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

Spring์—์„œ ์ œ๊ณตํ•˜๋Š” HandlerMethodArgumentResolver ๋ฅผ ํ™œ์šฉํ•˜์˜€๋‹ค.

ArgumentResolver๋Š” Controller์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

์ฆ‰ Controller์—์„œ๋Š” request๋ฅผ ์ง์ ‘ ๋‹ค๋ฃจ์ง€ ์•Š์•„๋„ ๋œ๋‹ค.


AuthUserArgumentResolver

Long userId = (Long) request.getAttribute("userId");
String email = (String) request.getAttribute("email");
UserRole userRole = UserRole.of((String) request.getAttribute("userRole"));

return new AuthUser(userId, email, userRole);

์ด ํด๋ž˜์Šค์˜ ์—ญํ• ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

request attribute์—์„œ ์ธ์ฆ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค
-> AuthUser ๊ฐ์ฒด ์ƒ์„ฑ
-> Controller ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ


Controller ์ฝ”๋“œ ๊ฐœ์„ 

๊ธฐ์กด ๋ฐฉ์‹

Long userId = (Long) request.getAttribute("userId");

๊ฐœ์„  ๋ฐฉ์‹

public ResponseEntity<CommentSaveResponse> saveComment(
        @Auth AuthUser authUser,
        ...
)

Controller์—์„œ๋Š” AuthUser ๊ฐ์ฒด๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.


๊ตฌ์กฐ ๊ฐœ์„  ํšจ๊ณผ

Controller -> ์ธ์ฆ ๋กœ์ง ์ œ๊ฑฐ
ArgumentResolver -> ์ธ์ฆ ๊ฐ์ฒด ์ƒ์„ฑ
Filter -> request attribute ์ €์žฅ

์ฆ‰ ๋‹ค์Œ ๊ตฌ์กฐ๊ฐ€ ๋งŒ๋“ค์–ด์กŒ๋‹ค.

JwtFilter
 -> JwtAuthHelper
 -> request attribute ์ €์žฅ

ArgumentResolver
 -> AuthUser ๊ฐ์ฒด ์ƒ์„ฑ

Controller
 -> AuthUser ์‚ฌ์šฉ

์ด ๊ตฌ์กฐ๋Š” ์‹ค์ œ Spring Security์˜ ์ธ์ฆ ํ๋ฆ„๊ณผ๋„ ์œ ์‚ฌํ•˜๋‹ค.

Lv6 ๋ฒจ๋กœ๊ทธ

Lv 6. ์œ„ ์ œ์‹œ๋œ ๊ธฐ๋Šฅ ์ด์™ธ ‘๋‚ด’๊ฐ€ ์ •์˜ํ•œ ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ ๊ณผ์ • - jiiimni ๋ฒจ๋กœ๊ทธ


Lv7 ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ๋ฐ ์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ •

์ด๋ฒˆ ๋‹จ๊ณ„์—์„œ๋Š” ์„œ๋น„์Šค ๋กœ์ง๊ณผ ์ธ์ฆ ๋กœ์ง์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜์˜€๋‹ค.

ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๋ชฉ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ฒ€์ฆ
  2. ๋ฆฌํŒฉํ† ๋ง ์•ˆ์ •์„ฑ ํ™•๋ณด
  3. ์ฝ”๋“œ ํ’ˆ์งˆ ํ–ฅ์ƒ

์ž‘์„ฑํ•œ ํ…Œ์ŠคํŠธ

Service ํ…Œ์ŠคํŠธ

CommentServiceTest
ManagerServiceTest
AuthServiceTest
UserServiceTest

Config ํ…Œ์ŠคํŠธ

JwtAuthHelperTest
GlobalExceptionHandlerTest
WebConfigTest
FilterConfigTest

ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€

IntelliJ Coverage ๊ธฐ์ค€

์ „์ฒด ํด๋ž˜์Šค ์ปค๋ฒ„๋ฆฌ์ง€ 77%
๋ฉ”์„œ๋“œ ์ปค๋ฒ„๋ฆฌ์ง€ 73%
๋ผ์ธ ์ปค๋ฒ„๋ฆฌ์ง€ 76%
Domain ํŒจํ‚ค์ง€ 82%
Config ํŒจํ‚ค์ง€ 81%


ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ์˜ˆ์‹œ

@Test
void ๋Œ“๊ธ€_์ƒ์„ฑ์—_์„ฑ๊ณตํ•œ๋‹ค() {

    given(todoRepository.findById(anyLong()))
            .willReturn(Optional.of(todo));

    CommentSaveResponse response =
            commentService.saveComment(authUser, 1L, request);

    assertEquals("๋Œ“๊ธ€", response.getContents());
}

์ด ํ…Œ์ŠคํŠธ๋Š” ๋‹ค์Œ ํ๋ฆ„์„ ๊ฒ€์ฆํ•œ๋‹ค.

Todo ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ
-> Comment ์ƒ์„ฑ
-> Response ๋ฐ˜ํ™˜


ํ…Œ์ŠคํŠธ ์ž‘์„ฑํ•˜๋ฉด์„œ ์•Œ๊ฒŒ ๋œ ์ 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ๋‹ค์Œ์„ ๋งŽ์ด ๋А๊ผˆ๋‹ค.

  1. ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๊ฐ€ ์ค‘์š”ํ•˜๋‹ค
  2. ์ฑ…์ž„ ๋ถ„๋ฆฌ๊ฐ€ ๋˜์–ด ์žˆ์–ด์•ผ ํ…Œ์ŠคํŠธ๊ฐ€ ์‰ฝ๋‹ค
  3. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ ๋ฆฌํŒฉํ† ๋ง ์•ˆ์ •์„ฑ์„ ๋†’์—ฌ์ค€๋‹ค

ํŠนํžˆ JwtFilter ๊ตฌ์กฐ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜๋ฉด์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์ด ํ›จ์”ฌ ์‰ฌ์›Œ์กŒ๋‹ค.


ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…

JWT Claims ํ…Œ์ŠคํŠธ ์˜ค๋ฅ˜

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ์ค‘ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

Cannot resolve symbol Claims

์›์ธ์€ build.gradle ์„ค์ •์ด์—ˆ๋‹ค.

๊ธฐ์กด ์„ค์ •

compileOnly 'io.jsonwebtoken:jjwt-api'

compileOnly๋Š” ํ…Œ์ŠคํŠธ ํด๋ž˜์ŠคํŒจ์Šค์— ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋ž˜์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ Claims๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ๋‹ค.


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

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์˜€๋‹ค.

implementation 'io.jsonwebtoken:jjwt-api'

์ดํ›„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ Claims๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.


ํšŒ๊ณ 

์ด๋ฒˆ ๋„์ „ ๊ธฐ๋Šฅ์—์„œ๋Š” ๋‹จ์ˆœํ•œ ๊ธฐ๋Šฅ ๊ตฌํ˜„๋ณด๋‹ค ์ฝ”๋“œ ๊ตฌ์กฐ ๊ฐœ์„ ๊ณผ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ๊ฒฝํ—˜์„ ๋งŽ์ด ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

JWT ์ธ์ฆ ๊ตฌ์กฐ ๋ฆฌํŒฉํ† ๋ง
-> ์ฑ…์ž„ ๋ถ„๋ฆฌ
-> ArgumentResolver ํ™œ์šฉ
-> ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ

์ด ๊ณผ์ •์„ ํ†ตํ•ด Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์กฐ๋ฅผ ๋” ๊นŠ์ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋˜ํ•œ Filter -> Helper -> Resolver -> Controller ๊ตฌ์กฐ๋Š”
Spring Security์˜ ์ธ์ฆ ํ๋ฆ„๊ณผ๋„ ์œ ์‚ฌํ•˜๋‹ค๋Š” ์ ์—์„œ ์˜๋ฏธ ์žˆ๋Š” ๊ฒฝํ—˜์ด์—ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ๊ณผ์ •์—์„œ๋Š” AI๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ํ…Œ์ŠคํŠธ ๊ตฌ์กฐ์™€ ์ž‘์„ฑ ๋ฐฉ๋ฒ•์„ ํ•™์Šตํ•˜์˜€๋‹ค.

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

์ด๋ฅผ ํ†ตํ•ด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๋ฐฉ์‹๊ณผ ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ •์— ๋Œ€ํ•œ ์ดํ•ด๋„๋ฅผ ๋†’์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.