跨域访问sessionid不一致问题

原创 2017年07月02日 19:09:54

在开发过程中遇到这么一个问题,让我花了一个下午的大好时光才解决。但是解决玩之后,发现那么的容易。就是查找资料的时候很费劲。这里把问题记录一下。

问题的产生

  • 流程是这样的,要做一个用户登录的接口。在登录页面,前端先请求验证码,然后输入用户名密码和验证码之后,请求登录接口。
  • 这里存在两个接口,验证码接口和登录接口。在验证码接口中我用session保存验证码,在登录接口中我从session取出验证码进行校验。
    两个接口的代码如下:
@RequestMapping("/getImageCode")
    public void getImageCode(HttpServletRequest request,
                             HttpServletResponse response) throws IOException {
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control",
                "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");

        String capText = captchaProducer.createText();
        request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY,capText);
        logger.info("code is "+capText+" session id is "+request.getSession().getId());
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public ModelMap login(HttpServletRequest request){
        ModelMapHelper helper = new ModelMapHelper();
        String userName = request.getParameter("userName");
        String password = request.getParameter("password");
        String imgCode = request.getParameter("imageCode");
        String sessionCode = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        logger.info("input code is "+imgCode+" session id is "+request.getSession().getId());
        if(StringUtils.isEmpty(imgCode)){
            helper.setErrorMap("验证码不能为空");
            return helper;
        }
        if(!imgCode.equals(sessionCode)){
            helper.setErrorMap("验证码不正确");
            return helper;
        }
        try {
            User user = userService.checkLogin(userName, password);
            if (user == null) {
                helper.setErrorMap("用户名或密码错误");
                return helper;
            }
            helper.setSuccessMap("登录成功");
            helper.setData(user);
            request.getSession().setAttribute("user",user);
        }catch (GeneralException g){
            g.printStackTrace();
            logger.warn(g.getMessage(),g);
            helper.setErrorMap(g.getMessage());
        }catch (Exception e){
            e.printStackTrace();
            logger.error("查询失败",e);
            helper.setInternalErrorMap();
        }
        return helper;
    }

*经过postman工具简单的接口测试之后,没有问题。但是与前端进行接口联调的时候发现了问题。
两次获取的sessionid不一致,导致在登录时候,没有获取session中的验证码!
问题

查找原因

百思不得其解!为什么用postman测试是正常的呢?而与前端联调就有这种问题。
原来后台是做了一个跨域访问的设置

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }

    // 设置跨域访问
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "TRACE")
                .allowCredentials(true);
    }
}

主要解释如下:
registry.allowedOrigins(““)设置跨域访问的域名,如果是,默认都可以访问。
这个方法是后来找到问题后,自己加上去的
registry.allowCredentials(true)设置是否允许客户端发送cookie信息。默认是false
具体关于这些头信息的解释可以参考:
http://www.ruanyifeng.com/blog/2016/04/cors.html

解决问题

其实最后就做了两件事情,
1. 服务端设置可以接收cookie信息

registry.allowCredentials(true)
  1. 在ajax请求中设置发送cookie信息
 $.ajax({
   url: a_cross_domain_url,
   xhrFields: {
      withCredentials: true
   }
});

再看看结果,sessionid就一致了。
这里写图片描述
参考的博客:
https://segmentfault.com/q/1010000002905817

版权声明:本文为博主原创文章,未经博主允许不得转载。

Ajax跨域请求保证同一个session的…

我们知道,根据浏览器的保护规则,跨域的时候我们创建的sessionId是不会被浏览器保存下来的,这样,当我们在进行跨域访问的时候,我们的sessionId就不会被保存下来,也就是说,每一次的请求,服务...
  • liliang950210
  • liliang950210
  • 2017年03月30日 10:44
  • 1701

解决 前后端分离 跨域 sessionid每次都变化

前端开发使用的VUE,后端使用的java,前后端分离,因为跨域问题JSESSIONID每次请求都会变化,解决方法如下: 前端要将withCredentials设为true 以ajax请求为例:...
  • huang369509940
  • huang369509940
  • 2017年08月29日 15:59
  • 1907

跨域请求,关于后端session会话丢失的解决办法

达人科技 2016-11-26 13:32 目前使用前后端分离的模式开发,后端提供跨域接口、前端jsonp调用,绑定数据,但是在该站点下有个人中心模块存在的情况下,服务端的session会话...
  • u011277123
  • u011277123
  • 2016年11月28日 09:38
  • 6752

每次发起的request获取的sessionid不一致问题

遇到类似问题的博客不少,也没几个能说出个所以然或是给出一个合理的解决方案的。 找到一个博客还可以:http://blog.csdn.net/u011521890/article/details/73...
  • shenya2
  • shenya2
  • 2017年10月07日 11:47
  • 565

ASP.NET MVC中sessionID一直变化的解决方法

今天要做一个功能,要用到会话的ID--sessionID,结果同一页面提交两次,两次得到的sessionID竟然不一样 后来想在Session初始化的时候记录下,结果发现Global里面没有Sessi...
  • liyifei21
  • liyifei21
  • 2013年07月13日 09:03
  • 5958

同域名下的多项目谨防sessionid互相影响,造成严重后果

同域名下的多项目谨防sessionid互相影响,造成严重后果,保持咱程序猿的优良传统,独立的命名空间,严格的洁癖症,处事不惊的顽强能力。转入正题 已我开发cctv项目为例,当然cctv愿意找我,我是很...
  • sl0007
  • sl0007
  • 2013年12月12日 10:51
  • 1845

常用跨域共用session

常用跨域共用session的是登录模块,我相信很多开发的朋友的都遇到过,只需要一个地方登录,相关联的网站也是处于登录状态。两种情况:一种9streets.cn和a.9streets.cn之间,另一种是...
  • u010708577
  • u010708577
  • 2014年06月20日 15:39
  • 840

解决页面的Session.SessionID不同的问题

今天突然发现apsx页面的session.SessionID在每次刷新或者点击按钮的时候,每次的SessionID都不同。和之前学到session是客户端与服务器端建立的会话,一但建立始终保存在服务器...
  • jianxue
  • jianxue
  • 2009年03月02日 23:26
  • 1000

后台跨域造成session失效

1.场景还原      最近在笔者在springboot中集成token机制发现了一个隐藏bug:“后台实现跨域,前端运用ajax请求后台接口成功回调;一切看似那么顺利,其实不然,session已经后...
  • zhangxing52077
  • zhangxing52077
  • 2017年06月12日 22:15
  • 4094

SESSION 跨域解决

关于session跨域的理解其实也很简单,我们都知道保存cookie的时候里面就有一个是domain的设置。 1setcookie('name',...
  • joeyon
  • joeyon
  • 2015年02月13日 15:24
  • 2922
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:跨域访问sessionid不一致问题
举报原因:
原因补充:

(最多只允许输入30个字)