简单请求的跨域以及安全校验

2018-01-05  本文已影响1085人  miaoLoveCode

前言

提起跨域,可能大多数猿们都不陌生,在工作中多多少少都有碰到,现在比较主流的跨域模式有cors和jsonp:

本文将讲解简单请求的cors跨域服务端如何做?安全校验如何做?

简单请求的cors跨域

注:什么叫简单请求?
浏览器将cors请求分为两类:简单请求(simple request)和非简单请求(not-so-simple request),只要同时满足以下条件的就属于简单请求,否则都属于非简单需求:

  1. 请求方法是HEADGETPOST之一;
  2. HTTP的头信息不超出以下几种字段:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type:只能取三个值application/x-www-form-urlencodedmultipart/form-datatext/plain
    • Last-Event-ID

当然浏览器对于这两种请求的处理也是有区别的,非简单请求浏览器会增加一次http查询请求(预检请求),先询问服务器当前请求域名是否在服务器的许可名单之中以及可以使用哪些http动词和头信息字段,只有得到正确的答复,浏览器才会发起一次正式的XMLHttpRequest请求,否则报错。

对于简单请求的cors跨域,具体的流程如下:

  1. 浏览器发起请求,在请求header中增加Origin字段,表示本次请求来自哪个源,具体的请求header如下所示:

    Accept:*/*
    Accept-Language:zh-CN,zh;q=0.9
    Connection:keep-alive
    Origin:https://miao.test.com
    User-Agent:Mozilla/5.0...
    
  2. 服务端接收到请求后,判断Origin指定的源,如果在允许调用的范围呢,服务端正常返回,需要注意的是,服务端在返回时需要在header中设置Access-Control-Allow-Origin字段,浏览器会判断该字段是否包含请求中的Origin值,如果包含,响应正确,否则,浏览器会抛出错误,正确响应header如下所示:

    Access-Control-Allow-Credentials:true
    Access-Control-Allow-Origin:https://miao.test.com
    Access-Control-Expose-Headers: FooBar
    Content-Type: text/html; charset=utf-8
    

    上文响应header中有3个与cors请求相关的字段:

    • Access-Control-Allow-Origin:必须要有的字段,它的值可以是请求header的Origin的值,也可以是*(表示接受任何域的请求),需要注意的是,如果为*的话,会有一系列的安全问题,建议不要这么做;
    • Access-Control-Allow-Credentials:可选字段,表示是否允许发送cookie,true表示允许,另外该字段的值只能设置为true,如果服务端不需要浏览器发送cookie,删除该字段就可以。需要注意的是,如果需要发送cookie还需要前端配合的,前端必须要在ajax请求中打开withCredentials属性;
    • Access-Control-Expose-Headers:可选字段,可以通过该字段指定获取响应header中的某个字段的值。

知道流程之后,那么对于cors跨域的安全怎么做也就一目了然了,可以直接判断请求的Origin是否在允许跨域的域名白名单内,如果在,则服务端允许返回正确响应,否则,服务端拦截,响应异常。接下来给个简单的例子吧,一看就会用:

安全校验Interceptor

跨域请求安全校验

服务端Controller处理
服务端的处理方式与正常同源请求响应一样,不需要像jsonp那样需要包装响应数据:

@RequestMapping(value = "/test.json", method = RequestMethod.POST)
  public void test(HttpServletRequest request, ModelMap modelMap) {
      try {
          modelMap.put("success", true);
          modelMap.put("data", "test");
      } catch (Exception e) {
          modelMap.put("success", false);
          modelMap.put("errCode", 1001);
          modelMap.put("errMsg", "系统异常");
      }
  }

到这里,简单请求的cors模式跨域就大致介绍完了,非简单请求大家在工作中其实不太常遇到,在这里我就不做详细的介绍了,以后遇到了再做相关介绍。就让我小小的放飞下自己~~~~~~

上一篇 下一篇

猜你喜欢

热点阅读