vue+springboot 跨域跨 session+cookie失效失 问题

2 篇文章 0 订阅
1 篇文章 0 订阅
主要介绍了前后端分离 vue+springboot 跨域 session+cookie 失效问题的解决方法,解决过程也很简单(该方法也适用于跨站请求)
首先登陆成功时将用户存在 session 中,后续请求在将用户从 session 中取出检查。后续请求取出的用户都为 null
首先发现 sessionID 不一致,导致每一次都是新的会话,当然不可能存在用户了。然后发现 cookie 浏览器不能自动保存,服务 器响应set-cookie
搜索问题,发现跨域,服务器响应的 setCookie 浏览器无法保存,而且就算保存了域名不同也不能携带。
第一步:
后台添加过滤器,因为前后端分离,不可能每个方法都写一遍,所以添加过滤器统一处理。
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(urlPatterns = "/*", filterName = "CORSFilter")
public class CORSFilter implements Filter {
@Override
public void destroy() {
}
/**
* 此过滤器只是处理跨域问题
* @param servletRequest
* @param servletResponse
* @param chain
* @throws ServletException
* @throws IOException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws ServletException, IOException {
    HttpServletRequest req = (HttpServletRequest) servletRequest;
    HttpServletResponse resp = (HttpServletResponse) servletResponse;
    String origin = req.getHeader("Origin");//注意发布生产时不能这么写,得写死固定可以访问的域名,否则不安全
    if(origin == null) {
        origin = req.getHeader("Referer");
    }
    resp.setHeader("Access-Control-Allow-Origin", origin);//这里不能写*,
    *代表接受所有域名访问,如写*则下面一行代码无效。谨记
    resp.setHeader("Access-Control-Allow-Credentials", "true");//true代表允许携带cookie
    chain.doFilter(servletRequest,servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}

springboot2.配置过滤器时,启动类必须加上@ServletComponentScan才会加载过滤器

然后前端配置
使用vue.resource发送请求时配置如下:
main.js中 Vue.http.options.xhr = { withCredentials: true }


使用vue.axios发送请求时配置如下:
axios.defaults.withCredentials = true;


jquery请求带上 xhrFields: {withCredentials: true}, crossDomain: true;
$.ajax({
type: "post",
url: "",
xhrFields: {withCredentials: true},
crossDomain: true,
data: {username:$("#username").val()},
dataType: "json",
success: function(data){ }
});
此时问题已解决。


如果还有问题,则是因为部分浏览器为了防止csrf等漏洞,需要设置samesite属性,像nodejs是是有专门的方法设置,然java后端的cookie现在还没有对应的设置方法,目前只能手动响应,代码如下
//Cookie cookie1 = new Cookie("test","test");
//cookie1.setPath("/");
//cookie1.setHttpOnly(true);
//response.addCookie(cookie1);
String header = response.getHeader("set-cookie");
response.setHeader("set-cookie",header+"; Secure; SameSite=None");

此解决方案:如果涉及到cookie无法设置过期时间,以下方法可解决。
 

//跨站设置cookie
String time = "; Max-Age=1209600; Expires=Tue, " + dateStrtoGMTStr(CommonConstant.FOURTEEN_DAY,CommonConstant.day);
response.setHeader("set-cookie", "JSESSIONID=" + WebContext.getSession().getId() + time + "; Path=/; HttpOnly; Secure; SameSite=None");


/*
 * 格日期变成字符串转为将林尼治时间字符串
 */
public String dateStrtoGMTStr(int num,String day) {
    Calendar cal = Calendar.getInstance();//使用默认时区和语言环境获得一个日历。
    if(num > 0){
        if(day.equals(CommonConstant.day)){
            cal.add(Calendar.DAY_OF_MONTH, +num);//取当前日期+天
        }else {
            cal.add(Calendar.HOUR_OF_DAY, +num);//取当前日期+小时
        }
    }
    Date time = cal.getTime();
    DateFormat format = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss z", Locale.US);
    format.setTimeZone(TimeZone.getTimeZone("GMT"));
    return format.format(time);
}


//设置默认的过期时长,如下:
response.setHeader("set-cookie", "JSESSIONID=" + WebContext.getSession().getId() + "; Path=/; HttpOnly; Secure; SameSite=None");


#############################################################
##  session设置默认的会话时长7200秒 取业务系统最长session时长    ##
#############################################################
session.maxInactiveIntervalInSeconds=7200
spring.session.store-type=none
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程治铭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值