[Spring] ๐Ÿฅท๐ŸปInterceptor๋ž€?

Sangho Hanยท2025๋…„ 4์›” 28์ผ
5

๐ŸŒฑ Spring

๋ชฉ๋ก ๋ณด๊ธฐ
9/12
post-thumbnail

๐Ÿ“Œ Interceptor?

์ธํ„ฐ์…‰ํ„ฐ๋Š” ์š”์ฒญ ์ „/ํ›„์˜ ๊ณตํ†ต ์ฒ˜๋ฆฌ ๋กœ์ง์„ ๋‹ด๋‹นํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ด๋‹ค.
์ด์ „์— ์ •๋ฆฌํ•œ Spring Filter์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ ๋™์ž‘ํ•˜๋Š” ๋ ˆ๋ฒจ์—์„œ์˜ ์ฐจ์ด์ ์ด ์กด์žฌํ•œ๋‹ค.

Interceptor ๐Ÿ†š Filter

[ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ]
       โ†“
    [Filter]
       โ†“
[DispatcherServlet]
       โ†“
  [Interceptor - preHandle()]
       โ†“
    [Controller]
       โ†“
  [Interceptor - postHandle()]
       โ†“
 [View Resolver & View]
       โ†“
[Interceptor - afterCompletion()]
       โ†“
    [Filter ์‘๋‹ต ์ฒ˜๋ฆฌ]
       โ†“
[ํด๋ผ์ด์–ธํŠธ ์‘๋‹ต]
  • ํ•„ํ„ฐ๋Š” ์„œ๋ธ”๋ › ์ŠคํŽ™์— ์†ํ•˜๊ณ , ์ธํ„ฐ์…‰ํ„ฐ๋Š” ์Šคํ”„๋ง MVC์— ์†ํ•œ๋‹ค.
    -> ๊ทธ๋ ‡๊ธฐ์— ํ•„ํ„ฐ๋Š” ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์— ๋…๋ฆฝ์ ์ด์ง€๋งŒ, ์ธํ„ฐ์…‰ํ„ฐ๋Š” ์Šคํ”„๋ง MVC์— ์ข…์†์ ์ด๋‹ค.
  • ํ•„ํ„ฐ๋Š” ๋””์ŠคํŒจ์ฒ˜์„œ๋ธ”๋ › ๋„๋‹ฌ ์ „์— ์ž‘๋™ํ•˜๋ฏ€๋กœ ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด ์ ์šฉ๋˜๋Š” ๋ฐ˜๋ฉด, ์ธํ„ฐ์…‰ํ„ฐ๋Š” ์ปจํŠธ๋กค๋Ÿฌ ํ•ธ๋“ค๋Ÿฌ ํ˜ธ์ถœ ์ „/ํ›„๋กœ๋งŒ ์ž‘๋™ํ•œ๋‹ค.
    -> ์ฆ‰, ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด ์ ์šฉ์„ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํ•„ํ„ฐ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆํ•˜๋‹ค.

๐Ÿ“Œ Interceptor ์ฃผ์š” ๋ฉ”์„œ๋“œ 3๊ฐ€์ง€

1. preHandle

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String token = request.getHeader("Authorization");
    if (token == null || !jwtProvider.isValid(token)) {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false; // ์ธ์ฆ ์‹คํŒจ: Controller๋กœ ๋„˜์–ด๊ฐ€์ง€ ์•Š์Œ
    }
    return true; // ์ธ์ฆ ์„ฑ๊ณต: ๋‹ค์Œ์œผ๋กœ ์ง„ํ–‰
}
  • ์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ ์ง์ „์— ๋™์ž‘ํ•œ๋‹ค.
  • ์š”์ฒญ ๊ฒ€์ฆ, ์ธ์ฆ, ํ๋ฆ„ ์ฐจ๋‹จ ๋“ฑ์— ํ™œ์šฉ๋œ๋‹ค.

2. postHandle

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                       ModelAndView modelAndView) throws Exception {
    if (modelAndView != null) {
        modelAndView.addObject("serverTime", LocalDateTime.now());
    }
}
  • ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์ง์ „ ๋™์ž‘ํ•œ๋‹ค.
  • ModelAndView ์กฐ์ž‘ ๋“ฑ ๊ณตํ†ต ๋ฐ์ดํ„ฐ ์‚ฝ์ž…์— ํ™œ์šฉ๋œ๋‹ค.

3. afterCompletion

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    long startTime = (long) request.getAttribute("startTime");
    long endTime = System.currentTimeMillis();
    System.out.println("์š”์ฒญ ์™„๋ฃŒ - ์ด ์†Œ์š” ์‹œ๊ฐ„: " + (endTime - startTime) + "ms");
}
  • ์š”์ฒญ/์‘๋‹ต ํ๋ฆ„์ด ์™„์ „ํžˆ ๋๋‚œ ํ›„์— ๋™์ž‘ํ•œ๋‹ค. ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋”๋ผ๋„ ๋ฌด์กฐ๊ฑด ๋™์ž‘ํ•œ๋‹ค.
  • ๋ฆฌ์†Œ์Šค ํ•ด์ œ, ์˜ˆ์™ธ ์ดํ›„ ์ฒ˜๋ฆฌ ๋“ฑ์— ํ™œ์šฉ๋œ๋‹ค.
  • try-catch-finally์—์„œ finally์™€ ์œ ์‚ฌํ•œ ๋А๋‚Œ์ด๋‹ค.

๐Ÿ“Œ ์™œ Interceptor๋ฅผ ์จ์•ผ ํ• ๊นŒ?

ํ•„ํ„ฐ๋ฅผ ์จ์„œ ์ด๋ฏธ ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด ๊ฑธ๋Ÿฌ์ค„ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์™œ ์ธํ„ฐ์…‰ํ„ฐ๊นŒ์ง€ ์“ฐ๋Š” ๊ฑธ๊นŒ?
์ด์— ๋Œ€ํ•œ ์ด์œ ๋“ค์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

1. ์ปจํŠธ๋กค๋Ÿฌ/๋น„์ฆˆ๋‹ˆ์Šค ํ๋ฆ„

ํ•„ํ„ฐ๋Š” HTTP ์š”์ฒญ/์‘๋‹ต ์ „์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•œ๋‹ค.
๋•Œ๋ฌธ์— ํ•ด๋‹น ์š”์ฒญ์ด ์–ด๋А ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๊ฐ€๊ณ , ์–ด๋– ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ํ๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.

๋ฐ˜๋ฉด ์ธํ„ฐ์…‰ํ„ฐ๋Š” ํ•ด๋‹น ์š”์ฒญ์ด ์–ด๋– ํ•œ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๊ฐ€๋Š”์ง€ ์•Œ๊ณ  ์žˆ์œผ๋ฉฐ, HandlerMethod๋ฅผ ํ†ตํ•ด์„œ ๋น„์ฆˆ๋‹ˆ์Šค ํ๋ฆ„, ์‚ฌ์šฉ๋œ ์–ด๋…ธํ…Œ์ด์…˜ ๋“ฑ์„ ๋ชจ๋‘ ํ™•์ธํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ์— ํ•„ํ„ฐ์— ๋น„ํ•ด์„œ ๋”์šฑ ์„ธ๋ฐ€ํ•œ ๊ฑฐ๋ฆ„๋ง์ด ๋˜์–ด์ค„ ์ˆ˜ ์žˆ๊ธฐ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

2. ๊ณตํ†ต ๋กœ์ง ๋ฐ ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ

์˜ˆ๋ฅผ ๋“ค์–ด์„œ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ API๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •์„ ํ•ด ๋ณด์ž.

@GetMapping("/api/user/profile")
public ResponseEntity<UserProfile> getProfile(HttpServletRequest request) {
    String token = request.getHeader("Authorization");

    if (token == null || !jwtProvider.validate(token)) {
        throw new UnauthorizedException();
    }

    // ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ํ”„๋กœํ•„ ์กฐํšŒ
    UserProfile profile = userService.getProfile(token);
    return ResponseEntity.ok(profile);
}

์œ„์™€ ๊ฐ™์€ ํ˜•ํƒœ๋ฅผ ๋„๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.

์ธ์ฆ์ด ํ•„์š”ํ•œ API๊ฐ€ 1~2๊ฐœ ์ •๋„๋ผ๋ฉด ํฐ ๋ฌธ์ œ๊ฐ€ ์•ˆ ๋˜๊ฒ ์ง€๋งŒ, ๋ณดํ†ต ๋Œ€๋ถ€๋ถ„์˜ API์—์„œ ์ธ์ฆ์„ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ํ•ด๋‹นํ•˜๋Š” ๋ชจ๋“  API ๋“ค์— ๋Œ€ํ•˜์—ฌ ์ธ์ฆ ์ฝ”๋“œ๊ฐ€ ๊ณตํ†ต์ ์œผ๋กœ ํฌํ•จ๋  ๊ฒƒ์ด๊ณ , ์ด๋Š” ์ฝ”๋“œ ์ค‘๋ณต์„ ์•ผ๊ธฐํ•œ๋‹ค.
๋˜ํ•œ ์˜ˆ์‹œ ์ฝ”๋“œ์—์„œ๋Š” ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ธ์ฆ๊นŒ์ง€ ๋งก๊ณ  ์žˆ๊ธฐ์—, ๊ด€์‹ฌ์‚ฌ๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ๋ถ„๋ฆฌ๋˜์ง€ ์•Š์•„ ๋ณด์ธ๋‹ค.

Interceptor ์‚ฌ์šฉ

Interceptor๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ์‹์œผ๋กœ ๊ฐœ์„ ์ด ๋ ๊นŒ?

public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");

        if (token == null || !jwtProvider.validate(token)) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
            return false;
        }

        return true; // ์ •์ƒ ํ†ต๊ณผ
    }
}

ํ† ํฐ ์œ ํšจ์„ฑ ๊ฒ€์ฆ๋งŒ ์ง„ํ–‰ํ•˜๋Š” AuthInterceptor๋ฅผ ๋งŒ๋“ค์–ด ๋‘”๋‹ค.

public class AdminInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");

        if (token == null || !jwtProvider.validate(token)) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
            return false;
        }

        UserInfo userInfo = jwtProvider.getUserInfo(token);
        if (!userInfo.isAdmin()) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden: Admins only");
            return false;
        }

        return true; // ์ •์ƒ ํ†ต๊ณผ
    }
}

ํ† ํฐ ์œ ํšจ์„ฑ ๊ฒ€์ฆ ์ดํ›„ ๊ด€๋ฆฌ์ž์ธ์ง€ ํ™•์ธ๊นŒ์ง€ ์ง„ํ–‰ํ•˜๋Š” AdminInterceptor ๋„ ๋งŒ๋“ค์–ด ๋‘”๋‹ค.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž ์ธ์ฆ์šฉ
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/api/users/**");

        // ๊ด€๋ฆฌ์ž ๊ถŒํ•œ ์ธ์ฆ์šฉ
        registry.addInterceptor(new AdminInterceptor())
                .addPathPatterns("/api/admin/**");

    }
}

์ด๋ฅผ WebMvcConfig์— ๋“ฑ๋กํ•จ์œผ๋กœ์จ ์œ„์—์„œ ๋งŒ๋“ค์–ด ๋‘” ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

.addPathPatterns("/api/users/**");๋Š” /api/users/** ์—”๋“œํฌ์ธํŠธ๋กœ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋Š” ๊ฒฝ์šฐ์— ์ž‘๋™ํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค.

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

์ธํ„ฐ์…‰ํ„ฐ์—์„œ๋„ ๊ณตํ†ต ๋กœ์ง ๋ถ„๋ฆฌ

ํ•˜์ง€๋งŒ ์œ„ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๋˜ ๋‹ค์‹œ ์ค‘๋ณต๋˜๋Š” ๋กœ์ง์ด ๋ณด์ธ๋‹ค.

if (token == null || !jwtProvider.validate(token)) {
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    return false;
}

๋ฐ”๋กœ ์ด ๋ถ€๋ถ„์ธ๋ฐ, ํ•ด๋‹น ๋ถ€๋ถ„๊นŒ์ง€ ๊ณตํ†ต ๋กœ์ง์œผ๋กœ ๋ถ„๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");

        if (token == null || !jwtProvider.validate(token)) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
            return false;
        }

        // ์œ ํšจํ•œ ํ† ํฐ์ด๋ฉด ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅ
        UserInfo userInfo = jwtProvider.getUserInfo(token);
        request.setAttribute("userInfo", userInfo); 

        return true;
    }
}

ํ† ํฐ ๊ฒ€์ฆ์„ ๋งˆ์นœ ํ›„, ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด ๋‹ค์Œ ์ธํ„ฐ์…‰ํ„ฐ ๋™์ž‘์„ ์œ„ํ•ด์„œ request์— ์œ ์ € ์ •๋ณด๋ฅผ ์ €์žฅํ•ด ๋‘”๋‹ค.

public class AdminInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");

        if (userInfo == null || !userInfo.isAdmin()) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden: Admins only");
            return false;
        }

        return true;
    }
}

๊ด€๋ฆฌ์ž์ธ์ง€ ๊นŒ์ง€ ํ™•์ธํ•ด์•ผ ํ•˜๋Š” API์—์„œ๋Š”, ์œ„ ๊ณผ์ •์—์„œ ์ €์žฅ๋œ ์œ ์ € ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์ตœ์ข… ํ™•์ธํ•˜๊ฒŒ ๋œ๋‹ค.

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new AuthInterceptor())
            .addPathPatterns("/api/users/**", "/api/admin/**");

    registry.addInterceptor(new AdminInterceptor())
            .addPathPatterns("/api/admin/**");
}

๋งˆ์ง€๋ง‰์œผ๋กœ ์ธํ„ฐ์…‰ํ„ฐ ๋“ฑ๋ก์„ ์ง„ํ–‰ํ•ด ์ฃผ๋ฉด ๋˜๋ฉฐ, AuthInterceptor์˜ ๋™์ž‘์ด ์„ ํ–‰๋˜์–ด์•ผ ํ•˜๊ธฐ์— ๋จผ์ € ๋“ฑ๋กํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.


๐Ÿ“Œ ๊ทธ๋ž˜์„œ Interceptor๋ฅผ ์“ฐ๊ณ  ์žˆ๋Š”๊ฐ€?

๊ฒฐ๋ก ๋ถ€ํ„ฐ ๋งํ•˜์ž๋ฉด ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Š๊ณ , ์ธ์ฆ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด์„œ Spring Security ์™€ JwtFilter๋ฅผ ํ™œ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

@Slf4j
@Component
@RequiredArgsConstructor
public class JwtFilter extends OncePerRequestFilter {

    private final JwtUtil jwtUtil;
    private final CustomUserDetailsService customUserDetailsService;

    /**
     * ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋ฉฐ JWT ๊ฒ€์ฆ ๋ฐ ์ธ์ฆ ์„ค์ •์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
     *
     * @param request     HTTP ์š”์ฒญ ๊ฐ์ฒด
     * @param response    HTTP ์‘๋‹ต ๊ฐ์ฒด
     * @param filterChain  ํ•„ํ„ฐ ์ฒด์ธ ๊ฐ์ฒด
     * @throws ServletException ์„œ๋ธ”๋ฆฟ ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ
     * @throws IOException      ์ž…์ถœ๋ ฅ ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            // โœ… OPTIONS ์š”์ฒญ์ผ ๊ฒฝ์šฐ ํ•„ํ„ฐ๋ฅผ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋ฐ”๋กœ ๋‹ค์Œ ํ•„ํ„ฐ ์‹คํ–‰
            if (request.getMethod().equalsIgnoreCase("OPTIONS")) {
                filterChain.doFilter(request, response);
                return;
            }
            String token = jwtUtil.getTokenFromHeader(request.getHeader("Authorization"));
            jwtUtil.validateToken(token);
            Long userId = jwtUtil.getClaimFromToken(token, "userId", Long.class);
            setAuthentication(userId);

        } catch (Exception e) {
            log.error("JWT validation failed: " + e.getMessage());
            SecurityContextHolder.clearContext();
        }
        filterChain.doFilter(request, response);
    }

    /**
     * ์ธ์ฆ ์ •๋ณด๋ฅผ SecurityContext์— ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
     *
     * @param userId ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์˜ ID
     */
    private void setAuthentication(Long userId) {
        UserDetails userDetails = customUserDetailsService.loadUserByUserId(userId);
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                userDetails,
                null,
                userDetails.getAuthorities()
        );
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }

    /**
     * ํŠน์ • ๊ฒฝ๋กœ์— ๋Œ€ํ•ด JWT ๊ฒ€์ฆ์„ ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค.
     *
     * @param request HTTP ์š”์ฒญ ๊ฐ์ฒด
     * @return true์ผ ๊ฒฝ์šฐ ํ•ด๋‹น ์š”์ฒญ์— ๋Œ€ํ•ด ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ•˜์ง€ ์•Š์Œ
     */
    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        String path = request.getServletPath();
        return path.startsWith("/api/v1/users/onboarding");
    }
}

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

๐Ÿ‘๐ŸปSpring Security + JwtFilter๋ฅผ ์“ฐ๋Š” ์ด์œ 

1. ๋”์šฑ ๋น ๋ฅด๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์š”์ฒญ ์ œ์–ด ๊ฐ€๋Šฅ

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

๋•Œ๋ฌธ์— ๋””์ŠคํŒจ์ฒ˜์„œ๋ธ”๋ › ์ดํ›„์— ์ธ์ฆ์ธ๊ฐ€๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ์ธํ„ฐ์…‰ํ„ฐ ๋ฐฉ์‹๋ณด๋‹ค ๋ณด์•ˆ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ถˆํ•„์š”ํ•œ ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๋„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

2. SecurityContext๋ฅผ ํ†ตํ•ด ์ธ์ฆ ์ •๋ณด๋ฅผ ์‹œ์Šคํ…œ ์ „์ฒด์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

์ธ์ฆ ์„ฑ๊ณต ํ›„, SecurityContext๋ผ๋Š” ์Šคํ”„๋ง ๋ณด์•ˆ ์ €์žฅ์†Œ์— ์ธ์ฆ ์ •๋ณด๋ฅผ ์ €์žฅํ•ด ๋‘˜ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ดํ›„ ํ”„๋ ˆ์  ํ…Œ์ด์…˜, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ์ด์–ด ์–ด๋””์„œ๋“ 
SecurityContextHolder.getContext().getAuthentication() ๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹น ์ •๋ณด๋ฅผ ๊บผ๋‚ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿง‘๐Ÿปโ€๐Ÿ’ป ๋” ๋งŽ์€ ์žฅ์ ์ด ์กด์žฌํ•˜๊ฒ ์ง€๋งŒ Spring Security์— ๋ฏธ์ˆ™ํ•œ ์ƒํƒœ๋กœ ์ ๋Š” ๊ฒƒ์€ ์ข‹์ง€ ์•Š์„ ๊ฒƒ ๊ฐ™์•„ ์ถ”ํ›„ ๋” ์•Œ์•„๋ณด๋ ค๊ณ  ํ•œ๋‹ค!

profile
์•ˆ๋…•ํ•˜์„ธ์š”. ๋น„์ฆˆ๋‹ˆ์Šค๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž, ํ•œ์ƒํ˜ธ์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€