본문 바로가기
개발 및 운영/Spring

spring-cloud Zuul 사용시 매번 Set-Cookie하는 경우

by Joseph.Lee 2018. 12. 26.

 spring-cloud-starter-netflix-zuul 을 이용하여 Gateway 사용시 매번 Request마다


Set-Cookie: SESSION=YjlmYjEzNzgtZTAzYy00NjEzLWJkYzItYTY5YTFiY2I3NDQy
Set-Cookie: SESSION=NDg1NGYwZDktYTM5ZC00YjBjLThiNDMtZjA0ZWZkYmFjYjQ1

이런식으로 세션 쿠키가 한개 이상이 매번 새로 생성되는 문제가 있었습니다..


일단 설정은...

sessionCreationPolicy은 Gateway에서만 ALWAYS으로, 나머지 Endpoint service에서는 NEVER으로 되어있고


Gateway에서 Zuul Filter으로 아래와 같이 Session ID을 넘겨주도록 했습니다.


public class SessionCookieFilter extends ZuulFilter {

@Autowired
private SessionRepository sessionRepository;

@Override
public String filterType() {
return "pre";
}

@Override
public int filterOrder() {
return 0;
}

@Override
public boolean shouldFilter() {
return true;
}

@Override
public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
HttpSession httpSession = request.getSession();
Session session = sessionRepository.findById(httpSession.getId());

context.addZuulRequestHeader("Cookie", "SESSION=" + httpSession.getId());
return null;
}
}


Spring-boot 소스를 뒤지고 뒤져.. 어디서 이런 현상이 발생하는지 찾아보았는데 (사실 처음엔 Zuul문제인 줄 알았습니다..ㅠㅠ 그래서..)


RequestContext의 addZuulResponseHeader에 브레이크포인터를 걸어놓고 디버깅 해 보았는데


SimpleHostRoutingFilter의 forward 자체에서 Set-Cookie 헤더가 날라왔습니다..


결국 End-point service 애플리케이션에서 Set-Cookie을 했다는 건데 찾아보니


SessionRepositoryFilter의 getRequestedSession 메서드에서  

private S getRequestedSession() {
if (!this.requestedSessionCached) {
List<String> sessionIds = SessionRepositoryFilter.this.httpSessionIdResolver
.resolveSessionIds(this);

resolveSessionIds 에서 세션 ID을 읽어오지 못했습니다.


@Override
public List<String> readCookieValues(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
List<String> matchingCookieValues = new ArrayList<>();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (this.cookieName.equals(cookie.getName())) {
String sessionId = (this.useBase64Encoding
? base64Decode(cookie.getValue()) : cookie.getValue());
if (sessionId == null) {
continue;
}

보니까 useBase64Encoding이 true라서 인코딩되지 않은 상태로 Gateway에서 날라온 SESSION cookie가 문제였습니다..


결국 SessionCookieFilter 에서 Base64 인코딩해서 던저줍니다~


(근데도 아직 가끔 중간에 랜덤하게? Set-Cookie으로 세션이 다시 생성되는 문제가...)


이런..

반응형

댓글