(필력이 조금 구립니다)


요새 MSA에 관심이 많아서


JWT Based 인증

Spring Cloud Gateway

Micro Backend Service


로 요청을 처리하는 플로우를 공부하고 있습니다 


-----


회원가입/유저 관련을 담당하는 서버를 짜보던 중 아래 의문이 들었습니다.


인증이 필요한 API, 인증이 필요 없는 API 에 각각 만료된 토큰으로 Gateway Server 에 요청을 날린다고 했을 때 그 처리 플로우가 어떻게 되는지 궁금합니다


인증 필요 API 예시 : GET /api/v1/user/me -> 현재 토큰에 해당하는 사용자 가져오기

인증 필요 없는 API 예시 :  GET /api/v1/user/{user_id} -> user_id에 해당하는 사용자 가져오기


-----


현재 작성한 gateway server 플로우입니다 


Gateway에 요청

-> 토큰 검증

-> valid 할 경우, 헤더에 X-User-Id 같은 거 설정 

-> 백엔드 서비스로 포워딩 


-----


요청 케이스에 대한 예상 응답은 


1. 만료된 토큰을 가지고 인증이 필요한 API에 요청을 날렸을 때

-> 당연히 token expired 응답이 넘어와야 함 


2. 만료된 토큰을 가지고 인증이 필요하지 않은 API에 요청을 날렸을 때

-> 이떄는 토큰이 없는 거 처럼 작동하여 정상 응답이 와야 함 


이렇게 생각합니다 


-----


Gateway 서버에서 토큰 검증을 할 때 아마 custom filter를 만들고, spring security configuration에 filter를 등록하는 방식으로 처리하는 게 보통의 처리 방법일텐데,


case 1 :

토큰이 만료되었을 때 security context에 user 정보를 비워둔채로 다음 필터로 넘어가기

-> 토큰 만료와 토큰이 존재하지 않는 것을 구분을 하지 못 함 

-> (인증이 필요한 API + 만료된 토큰) 조합에서 token required와 token expired 를 구분하지 못 함 


case 2:

토큰이 만료 되었을 때 바로 token expired 응답을 하기

-> (인증이 필요 없는 API + 만료된 토큰) 조합에서 정상 응답을 기대했는데 토큰 만료 응답이 오게 됨 


두 경우 모두 예상과 달리 문제가 생깁니다 


-----


이 문제의 근원지는 gateway에서는 API의 인증 여부를 모르기 때문에 생기는 일이라고 생각합니다

-> 그렇다고 uri에 /api/public/** 이런 식으로 인증 여부를 포함하는 건 좋은 방법이 아닌 거 같음 

-> 한 서비스에는 인증이 필요한 / 불필요한 API가 섞여있어서 routes 정의에 loginRequired = true 같은 것을 설정하지도 못 함 


그렇다고 해서 만료 여부는 판단하지 않고, 토큰 format과 파싱 후 토큰을 넘겨서 백엔드에서도 검증하는 것은 Gateway 서버를 쓰는 이유가 없다고 생각합니다 

-> 인증/인가 작업이 Gateway와 각 서비스에 중복으로 작성됨 


-----


Gateway은 인증/인가 후 포워딩이라는 역할에 충실, micro service는 비즈니스 로직 처리 등에만 집중하는 것이 좋은 구조라고 생각하는데, 깔끔하게 떨어지지 않는 느낌입니다 ,,


제가 아예 gateway + MSA에 대해 잘못 이해한 것인지, 보통 이런 경우에는 어떤 것이 컨벤션인지 궁금합니다 


고수분들의 도움이 필요합니다

감사합니다