Session not replicated on session creation with Spring Boot, Session, and Redis

被刻印的时光 ゝ 提交于 2019-12-03 03:39:37
Andrew Serff

Thanks to shobull for pointing me to Justin Taylor's answer to this problem. For completeness, I wanted to put the full answer here too. It's a two part solution:

  1. Make Spring Session commit eagerly - since spring-session v1.0 there is annotation property @EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE) which saves session data into Redis immediately. Documentation here.
  2. Simple Zuul filter for adding session into current request's header:

    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import javax.servlet.http.HttpSession;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.session.Session;
    import org.springframework.session.SessionRepository;
    import org.springframework.stereotype.Component;
    
    @Component
    public class SessionSavingZuulPreFilter extends ZuulFilter {
        @Autowired
        private SessionRepository repository;
    
        private static final Logger log = LoggerFactory.getLogger(SessionSavingZuulPreFilter.class);
    
        @Override
        public String filterType() {
            return "pre";
        }
    
        @Override
        public int filterOrder() {
            return 1;
        }
    
        @Override
        public boolean shouldFilter() {
            return true;
        }
    
        @Override
        public Object run() {
            RequestContext context = RequestContext.getCurrentContext();
    
            HttpSession httpSession = context.getRequest().getSession();
            Session session = repository.getSession(httpSession.getId());
    
            context.addZuulRequestHeader("Cookie", "SESSION=" + httpSession.getId());
    
            log.trace("ZuulPreFilter session proxy: {}", session.getId());
    
            return null;
        }
    }
    

Both of these should be within your Zuul Proxy.

Spring Session support currently writes to the data store when the request is committed. This is to try to reduce "chatty traffic" by writing all attributes at once.

It is recognized that this is not ideal for some scenarios (like the one you are facing). For these we have spring-session/issues/250. The workaround is to copy RedisOperationsSessionRepository and invoke saveDelta anytime property is changed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!