跨域问题笔记

最近是前后端分离的一个项目,因为是产品各自分开独立编写,在合并测试的时候,出现了那么一个跨域访问的问题,这是正常哦,不同于常规的web项目那样资源与逻辑层相结合。想想这些问题总是会出现,出现了匆忙解决还不如记录下来,自己查阅,来的及时。

目录

同源与跨域

这个同源策略?

前后端分离怎么办?

全局配置:

    局部配置


同源与跨域

    简单地说,在一个浏览器中访问的网站不能访问另一个网站中的数据,除非这两个网站具有相同的Origin,也即是拥有相同的协议、主机地址以及端口。一旦这三项数据中有一项不同,那么该资源就将被认为是从不同的Origin得来的,也就是跨域,进而不被允许访问

    详细点  ——> 浏览器的同源策略还有坑爹的IE端口号例外

    想必你也不会点进去看,那么就是干: 同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

这个同源策略?

   那为什么要用这个同源,主要是防止什么的安全机制?突然想起,我们会在进入项目层时会调取Cookies的内容作为验证条件,这个是一个问题,别人可以肆意修改内容。

其实这里,对于Session简单判断空的做法也是会有问题的:

        HttpSession session = request.getSession(true);
        这样简单的判断应该不会再次出现,否则直接cookie乱填一个就可以进入

当然,还有一个问题,就是利用上面提到的脚本,直接打印Cookie出来存储获取,这里往深点可以XSS脚本攻击点入

教你做人的alert
<script>alert(document.cookie)"></script>

前后端分离怎么办?

 哦?你说JSONP,借助同源策略对一些标签比如script、img这样的获取资源的标签是没有跨域限制的,然后利用这个东西实现跨域。这个方式可以自行谷歌或 ——> JSONP的实现方式

       同源策略其实是在浏览器上实现的,通过屏蔽响应结果的方式保证信息安全,也就是说浏览器并没有阻止发起跨域请求 ,有没有了解过头文件,它是通过头文件来确定指定网站是否支持跨域来决定是否返回响应结果。

       

      例如:我们对一个示例网站进行简单的get访问

请求:
Accept: application/json, text/javascript, */*; q=0.01
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Content-Length: 32
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: city=%u5E7F%u5DDE; JSESSIONID=F9912D37318665581FACC755FBBF024E; msgorder=; msgnormal=
Host: www.coffeeandice.com
Origin: http://www.coffeeandice.com
Referer: http://www.coffeeandice.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
X-Requested-With: XMLHttpRequest

响应结果:

HTTP/1.1 200 OK
Date: Sat, 04 Mar 2017 14:23:53 GMT
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked

注意:请求中的Origin 代表了请求的源,而响应 中 Access-Control-Allow-Origin 表示允许跨域的内容,例如:本例子中的 coffeeancice.com ,就可以访问这个源下的资源,如果是 * ,代表允许任何请求的跨域访问。

  当然,实际上的跨域请求不可能只有个get请求那么简单,详细参照 http://www.ruanyifeng.com/blog/2016/04/cors.html

   SpringMvc 4.2版本 以上,相应参数见源码 -->WebMvcConfigure

全局配置:

         亏得起之前配置的环境 4.2 以下的老项目搬运,利用过滤器自己加上头标题,然后web.xml 配置过滤器上去,稳健。

public class CrossDomainFilter extends CORSRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type");
        filterChain.doFilter(request, response);
    }
}

     4.2以上,包含在SpringBoot环境内,至于@Configuration这个注解主要是读取配置进去用的。

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
 
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**/*").allowedOrigins("*");
    }
}

    局部配置

如果只是需要特定接口需要跨域,我们只需要@CrossOrigin 来在控制层或方法上操作就可以了

@CrossOrigin(origins = "http://192.168.1.6:8080", maxAge = 3600)
@RequestMapping("free_index")
@RestController
public class IndexController{
    //a lot of code
}

参数解析:我就知道我后面糊懒得翻看源码,给自己留活路- -

     

      *表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
allowedOrigins("*")

      表示允许进入的方法
.allowedMethods("*")

      表示允许的请求头部
.allowedHeaders("*")

      允许Cookie跨域
.allowCredentials(true)

      允许访问的头信息
.exposedHeaders(HttpHeaders.SET_COOKIE) 

      预检请求的有效期
.maxAge(3600L);

 

猜你喜欢

转载自blog.csdn.net/CoffeeAndIce/article/details/83359334