JSCODE Logo
프로그래밍 과외블로그후기멘토진
회사명 : JSCODE대표 : 박재성사업자 등록번호 : 244-22-01557통신판매업 : 제 2023-인천미추홀-0381 호
학원 명칭 : 제이에스코드(JSCODE)원격학원학원설립ㆍ운영 등록번호 : 제6063호

서울특별시 구로구 경인로 20가길 11(오류동, 아델리아)

Copyright ⓒ 2025 JSCODE - 최상위 현업 개발자들의 프로그래밍 교육 All rights reserved.

이용약관개인정보처리방침
← 블로그 목록으로 돌아가기

[실습] API Gateway에 JWT 인증 로직 구현하기 (

JSCODE 박재성
JSCODE 박재성
2025-12-06
author
JSCODE 박재성
category
MSA
createdAt
Dec 6, 2025
series
비전공자도 이해할 수 있는 MSA 입문/실전
slug
practice-jwt-on-api-gateway
type
post
updatedAt
Dec 6, 2025 05:47 AM

✅ 설계

API Gateway로 들어오는 요청에 대해 비즈니스 로직을 처리할 수 있는 Filter 기능을 가지고 있다. 그래서 이 Filter 기능을 활용해 아래와 같이 JWT 인증 로직을 구현하고자 한다.
notion image
 
 
 

✅ API Gateway에 JWT 인증 로직 구현하기

  1. JWT 의존성 추가하기
    1. build.gradle
      ... dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-gateway-server-webflux' implementation 'io.jsonwebtoken:jjwt-api:0.13.0' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.13.0' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.13.0' developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'io.projectreactor:reactor-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } ...
      notion image
       
  1. application.yml 수정하기
    1. application.yml
      ... jwt: secret: jscode-secret-1234-1234-1234-1234
       
  1. JwtAuthenticationFilter
    1. @Component public class JwtAuthenticationFilter extends AbstractGatewayFilterFactory { @Value("${jwt.secret}") private String jwtSecret; @Override public GatewayFilter apply(Object config) { return (exchange, chain) -> { // Reqeuest Header에서 토큰 가져오기 String token = exchange.getRequest() .getHeaders() .getFirst("Authorization"); System.out.println("토큰 : " + token); // 토큰이 없을 경우 401 Unauthorized로 응답 if (token == null) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } // SecretKey로 토큰 검증 및 Payload(userId 담겨있음) 가져오기 SecretKey secretKey = Keys.hmacShaKeyFor(jwtSecret.getBytes(StandardCharsets.UTF_8)); String subject = Jwts.parser() .verifyWith(secretKey) .build() .parseSignedClaims(token) .getPayload() .getSubject(); System.out.println("userId : " + subject); // Payload를 X-User-Id 헤더에 담아서 Request 전달 // (= 다른 마이크로서비스에 요청 전달할 때 userId 정보를 담아서 보냄) return chain.filter( exchange.mutate() .request( exchange.getRequest() .mutate() .header("X-User-Id", subject) .build() ) .build() ); }; } }
      참고) JWT 토큰 검증 로직을 더 자세히 작성할 수도 있지만 프로젝트의 심플함을 위해 간단하게 작성했다.
 
 

✅ 라우팅 설정하기

외부 클라이언트가 사용하는 API는 아래의 API 밖에 없다. 이 중에서 JWT 인증을 거쳐야 하는 API는 게시글 생성 API 밖에 없다. 게시글 생성 API에만 JwtAuthenticationFilter를 적용시켜보자.
 
[사용자 서비스]
  • 회원가입 (POST /users/sign-up) - 외부용 API
  • 로그인 (POST /users/login) - 외부용 API
 
[게시글 서비스]
  • 게시글 생성 (POST /boards) - 외부용 API
  • 특정 게시글 조회 (GET /boards/{boardId}) - 외부용 API
  • 전체 게시글 조회 (GET /boards) - 외부용 API
 
  1. application.yml 코드 수정하기
    1. application.yml
      server: port: 8000 spring: cloud: gateway: server: webflux: routes: - id: user-service uri: http://localhost:8080 predicates: - Path=/api/users/** - id: board-service-jwt uri: http://localhost:8081 predicates: - Path=/api/boards - Method=POST filters: - JwtAuthenticationFilter - id: board-service uri: http://localhost:8081 predicates: - Path=/api/boards/** jwt: secret: jscode-secret-1234-1234-1234-1234
      • 주의) routes에서 설정한 순서대로 처리하기 때문에 board-service 위에 board-service-jwt에 대한 설정값을 작성해야 한다.
 
  1. 서버 다시 실행시키기
    1.  
  1. Header에 토큰 안 넣고, 게시글 작성 API 요청 보내보기
    1. notion image
      API Gateway의 인증 로직에 따라 요청이 잘 가로막혔다.
 
  1. Header에 토큰 넣고 요청 보내보기
    1. 로그인 API로 토큰 발급받기
      1. notion image
         
    2. 발급받은 토큰을 Header에 넣고, 게시글 작성 API 요청 보내보기
      1. notion image
        notion image
        정상적으로 게시글 작성이 된 걸 확인할 수 있다.
 
 
author
JSCODE 박재성
category
MSA
createdAt
Dec 6, 2025
series
비전공자도 이해할 수 있는 MSA 입문/실전
slug
type
series-footer
updatedAt
Dec 6, 2025 05:45 AM
📎
이 글은 비전공자도 이해할 수 있는 MSA 입문/실전 강의의 수업 자료 중 일부입니다.