V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ukipoi
V2EX  ›  Java

请教一下关于跨域方面的问题,主要是后台、springboot 方面的问题。

  •  
  •   ukipoi · 2018-12-03 12:49:16 +08:00 · 2401 次点击
    这是一个创建于 1963 天前的主题,其中的信息可能已经有所发展或是发生改变。

    SpringSession,右边这个"spring-session-data-redis",是怎么实现共享的?存放在 redis 里就是共享吗?
    但是我在使用过程中获取 session 还是 request.getSession(),那我要怎么根据 session.getId()来获得我想要的 session 呢?
    我觉得上面的问题只要是我不理解跨域是怎么回事。我现在遇到了这么一个问题。有一个后台访问的端口是 8081,而前台的页面是在 80 端口上的,所以前台所有的 ajax 请求,我在后台 request.getSession().getId()都是不一样的,这种情况就是跨域问题吧?
    一开始的时候找到一些解决跨域的方法,但是好像没有什么效果,而且自己也没理解是什么原理。自己猜测跨域的原因是服务器禁止了一些不符合要求的请求访问,这些解决跨域的方法是允许这些请求的访问。请问这个理解对么?

    @Configuration
    public class CorsConfig {
        private CorsConfiguration buildConfig() {
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.addAllowedOrigin("*"); 
            corsConfiguration.addAllowedHeader("*"); 
            corsConfiguration.addAllowedMethod("*");
            return corsConfiguration;
        }
    
        @Bean
        public CorsFilter corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", buildConfig());
            return new CorsFilter(source);
        }
    }
    
    @Configuration
    public class CrossInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
            if (request.getHeader(HttpHeaders.ORIGIN) != null) {
                String origin = request.getHeader("Origin");
                response.addHeader("Access-Control-Allow-Origin", origin);
                response.addHeader("Access-Control-Allow-Credentials", "true");
                response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT,PATCH, HEAD");
                response.addHeader("Access-Control-Allow-Headers", "Content-Type");
                response.addHeader("Access-Control-Max-Age", "3600");
            }
            return true;
        }
    }
    

    不好意思,我有点找不到学习的方向了,希望各位大大给我指点一下,不要嫌弃我伸手呀。

    11 条回复    2018-12-05 20:02:18 +08:00
    ayase252
        1
    ayase252  
       2018-12-03 12:58:49 +08:00   ❤️ 1
    跨域是因为前端浏览器为了安全,限制了对非同源资源的请求。用 CORS 可以让前端发起跨域请求,但是需要服务器的配合。可以看一下这篇[文档]( https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS)
    qinxi
        2
    qinxi  
       2018-12-03 13:24:22 +08:00   ❤️ 1
    跨域跟 session 有什么关系..
    跨域是浏览器实现的限制.
    如果只是处理跨域
    @Bean
    public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");//调用方域名
    config.addAllowedHeader("*");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("DELETE");
    config.addAllowedMethod("OPTIONS");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
    }

    session 这个东西你就把他当作是一个 map. 以前是在单机上.spring-session-redis 只是把这个东西变成共享的了.
    集群更方便.

    session 和跨域没啥关系, 默认情况下:只要你带上正确的 cookie, 请求就可以被正常的处理, 之后浏览器才会针对 ResponseHeader 做跨域检测.

    由于上面说的方式会存在风险: 就算不让跨域, 可是服务端已经处理了.

    options 请求.用来预检测是否允许接下来的实际请求. 这个请求通常没有实际作用.

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
    chanchan
        3
    chanchan  
       2018-12-03 13:30:42 +08:00
    复制一段阿里云文档的内容给你看看:
    跨域访问,或者说 JavaScript 的跨域访问问题,是浏览器出于安全考虑而设置的一个限制,即同源策略。当来自于 A 网站的页面中的 JavaScript 代码希望访问 B 网站的时候,浏览器会拒绝该访问,因为 A、B 两个网站是属于不同的域。

    在实际应用中,经常会有跨域访问的需求,比如用户的网站 www.a.com ,后端使用了 OSS。在网页中提供了使用

    JavaScript 实现的上传功能,但是在该页面中,只能向 www.a.com 发送请求,向其他网站发送的请求都会被浏览器拒绝。这样就导致用户上传的数据必须从 www.a.com 中转。如果设置了跨域访问的话,用户就可以直接上传到 OSS 而无需从 www.a.com 中转。
    -----------------------------------------------------------
    我感觉你已经解决了跨域问题,你接下来要解决的是让 sessionId 保持不变
    ukipoi
        4
    ukipoi  
    OP
       2018-12-03 14:10:59 +08:00
    @chanchan
    但是,如果网页和后台放在一起,sessionId 就可以保持不变。
    分开的话,sessionId 就会一直变化了。造成这个的原因不是因为跨域吗?
    sutra
        5
    sutra  
       2018-12-03 14:19:49 +08:00
    sessionId 变化是因为你是采用的 cookie 跟踪 Session 吧。
    V2XEX
        6
    V2XEX  
       2018-12-03 14:23:13 +08:00 via Android
    @ukipoi 你确定 session 变化是由于跨域造成的?请你说清楚你的使用场景
    wly19960911
        7
    wly19960911  
       2018-12-03 14:26:59 +08:00
    首先去看看 session 的原理,session id 和 session 的关系,还有 sessionid 存放在浏览器哪里( cookies )。

    跨域问题,使用插件可以解决 https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi,这个成本相对比较低,真正解决需要反向代理,如果可以的话解释下,为什么前端和后端端口不一致,前端 npm start 启动了调试服务器吗,这个的话,npm 有个 proxyTable 去处理反代问题
    chanchan
        8
    chanchan  
       2018-12-03 14:35:14 +08:00
    @ukipoi 也是因为跨域。那我说准确点,你已经解决跨域禁止访问的问题了,还需解决跨域 sessionId 一直变的问题
    ukipoi
        9
    ukipoi  
    OP
       2018-12-03 14:40:47 +08:00
    @V2XEX
    springboot 的项目,直接使用了 springsession 和 redis。
    然后前台页面是放在一个端口为 80 的容器,后台程序是放在一个端口 8081 的容器。
    在 80 端口的页面访问 8081 端口的后台。后台通过 request.getSession 获取 httpSession。
    不过看样子是我没设置 Access-Control-Allow-Credentials: true 和前台没有在 Ajax 请求里加上[ xhrFields: { withCredentials: true},crossDomain: true, ]的问题。
    haoz1w0w
        10
    haoz1w0w  
       2018-12-03 14:51:20 +08:00
    @ukipoi 如果我没记错的话 设置了 Access-Control-Allow-Credentials: true 的话 config.addAllowedOrigin("*");//调用方域名 就不能用*了 要去动态获取一下 response.setHeader("Access-Control-Allow-Origin", ((HttpServletRequest) request).getHeader("Origin"));
    YzSama
        11
    YzSama  
       2018-12-05 20:02:18 +08:00
    跨域和 session 共享不是一个问题吧。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1186 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 23:16 · PVG 07:16 · LAX 16:16 · JFK 19:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.