后端跨域cookie问题与spring-session-data-redis

背景

1、后端统一接入了公司内部登录系统,登录后cookie信息在域名:test.net.cn下。
Set-Cookie:SESSION=09a2f617-66a0-4e02-b99f-130d83900321; Domain=test.net.cn; Path=/; HttpOnly; SameSite=Lax

2、当我们的系统接入到统一登录系统后,若访问域名为a.test.net.cn,则不会出现问题,因为在他的子域名下,cookie是共享的,当跳转到我们系统后

sessionid是不会重新生成的,没问题

3、当我们的系统接入到统一登录系统后,若访问域名为a.test.net.cn:2531,则就会出现问题,因为域名不同,请求到后端,框架会认为本次请求不是同一个会话,

所以会在a.test.net.cn下再次写入一个cookie携带sessionId(说明:cookie的写入,domain是自动过滤端口的)

 

解释:

后端什么时候会判断写入cookie了,requset.getSeesion().getAttribute("");这个方法就会写入,查看源码可知,request.getSession();这个方法,默认为:

若本次请求的host下没有sessionId,则判断为新的会话,会重新创建一个sessionId,并写入到响应头里去:

Set-Cookie:SESSION=09a2f617-66a0-4e02-b99f-130d83900321; Domain=test.net.cn; Path=/; HttpOnly; SameSite=Lax
 
 

解决方案:

1、添加cookie写入值配置

import org.springframework.session.web.http.DefaultCookieSerializer;

public class NonWriteCookieSerializer extends DefaultCookieSerializer {

    @Override
    public void writeCookieValue(CookieValue cookieValue) {
    }
}

2、配置后端cookie配置


pattern: ^.+?\.(\w+\.\w+\.[a-z]+)$
 @Bean
    public DefaultCookieSerializer defaultCookieSerializer() {
        DefaultCookieSerializer cookieSerializer = new NonWriteCookieSerializer();
        cookieSerializer.setDomainNamePattern(pattern);
        cookieSerializer.setUseBase64Encoding(false);
        return cookieSerializer;
    }
注意:\的问题,直接写入到字符串里面为:

 

cookieSerializer.setDomainNamePattern("^.+?\\.(\\w+\\.\\w+\\.[a-z]+)$");
该正则表达式为任意域名,也就是和当前的cookie会话域名保持一致

 

3、设置request.getSession()方法,防止重复写入session

request.getSession(false).getAttribute(Constants.SESSION_ATTRIBUTE_USER);

这样可以防止重新创建sessionId,以及就算框架写入cookie其实值也是写不进去的,保证每次会话请求的sessionId与test.net.cn保持一致。

大功告成:这样就算登录的域名和子系统的域名不在同一个域名下,也可以通过spring-session-data-redis保持登录的统一性

建议:作为正式系统,还是建议各个子系统和登录系统在同一个域名下,这样才是最合规的

posted @ 2024-05-15 14:20  xzlnuli  阅读(40)  评论(0编辑  收藏  举报