

이전 프로젝트를 사용해서 실습을 진행하기로 한다. 변경된 점은 Auth 서버가 인증을 담당해, GateWay 서버에서 인증 필터를 거쳐서 인증이 된 사용자만 다른 서버로 route 가능하게 하는 테스트를 진행한다.
Auth 서버에는 로그인을 거쳐서 access token을 만들어주는 역할만 한다.
Gateway 서버에서는 모든 요청을 검사하는 인증 필터를 구현한다.
@Slf4j
@Component
public class LocalJwtAuthenticationFilter implements GlobalFilter {
@Value("${service.jwt.secret-key}")
private String secretKey;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
if (path.equals("/auth/signIn")) {
return chain.filter(exchange); // /signIn 경로는 필터를 적용하지 않음
}
String token = extractToken(exchange);
if (token == null || !validateToken(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
private String extractToken(ServerWebExchange exchange) {
// Authorization 헤더에서 토큰 꺼내오기
}
private boolean validateToken(String token) {
// 토큰 검증 로직
}
}
/auth/signIn 즉, 로그인은 토큰검사를 수행하지않고, 나머지 요청에 대해서는 토큰 검증을 하는 간단한 코드다.

테스트를 하기 위해서 eureka 서버, auth 서버, product 서버를 띄웠다.

위는 19091 포트로 띄워진 GateWay 서버를 통해 auth 서버의 로그인 api로 요청을 보내 access token 을 받아오는 과정이다. 테스트를 위해 쿼리 파라미터에 GET 메서드로 받은 점을 이해하길 바란다.

위는 19091 포트로 띄워진 GateWay 서버를 통해 product 서버의 api를 호출한 결과이다. GateWay의 서버의 LocalJwtAuthenticationFilter 를 거치다가 access token 즉, 인증 정보가 없기 때문에 401 인증 오류를 뜬 것을 확인할 수 있다.

이는 Postman 을 통해 헤더에 토큰을 넣은 채로 요청하면 제대로 결과를 내뱉는 것을 확인할 수 있다.

위는 19093 포트로 띄워진 product 서버로 직접 접근해 api를 호출한 결과이다. product 서버에서는 인증에 대한 처리가 없기 때문에 당연하게도 접근이 가능해 진다.
이는 실제로 사용할때는 방화벽을 통해 GateWay 서버만 외부로 접근을 허용해 단일 접근 지점으로 사용하고, 나머지 서버는 외부로부터 닫아놔야 한다. 이는 AWS에서 제공하는 기능으로 쉽게 구현 가능할 것 같다.
이번엔 MSA 환경에서 JWT를 이용한 인증과정을 간단하게 구현해 보았다. 나는 주로 JWT를 많이 사용해봤기에 flow가 쉽게 이해됐다.
인증의 시점으로는 GateWay에서 진행해도 되고, 각각의 서버에서 필요할 때 진행해도 된다.
그리고 ADMIN 기능 같은 높은 권한이 들어와 작업을 진행할때는 세션방식처럼 auth 서버에게 직접 질의를 진행해도 될 것 같다.
그래도 MSA 환경에서는 stateless 하게 JWT를 사용하는 것이 부하를 줄일 수 있다. 세션방식처럼 stateful 한 환경이라면 매 요청마다 auth 서버에게 질의를해 auth 서버가 터질수도 있을 터이기에.
결론은 인증 방법은 프로젝트의 상황에 맞게 적용하기로! (뭐든 그렇겠지만..)