zoukankan      html  css  js  c++  java
  • JS篇 同源策略、CORS、XSS、SessionCookie

    同源策略:

    如何引用: (iFrame指的是iframe DOM节点)
    1. 引用iframe的window对象:iFrame.contentWindow
    2. 引用iframe的document对象:iFrame.contentDocument,或者:iFrame.contentWindow.document

     

    示例:

    两个页面,前者页面中嵌入iframe,src指向后者:
    1. test.nuomi.com/link1.vm
    2. nuomi.com/link2.vm;

     

    同源要求:Protocols, domains, and ports均相同
    子域名不同的两个站:test.nuomi.com, nuomi.com,如果要通信,必须设置为统一的域名:document.domain=nuomi.com;
    即使其中一个已经是域名:nuomi.com,仍然需要明确调用:document.domain=nuomi.com;

     

    document.domain设值:
    1. 只能是当前域名的suffix,否则报错:Uncaught SecurityError: Failed to set the 'domain' property on 'Document': 'test' is not a suffix of 'test.nuomi.com'.
    2. 设值为com也会报错:'com' is a top-level domain.
    3. 必须是"."点分隔的后缀,否则报错:'mi.com' is not a suffix of 'test.nuomi.com'

     

    不同源时:

    1. 外面访问里面window的document属性:iFrame.contentDocument
    Chrome报错:  Uncaught SecurityError: ... Protocols, domains, and ports must match.
    Firefox报错:   null
    IE9报错:      SCRIPT5: 拒绝访问

    2. 里面访问外面window的document属性:window.parent.document
    Chrome报错:  Uncaught SecurityError: ... Protocols, domains, and ports must match.
    Firefox报错:   Permission denied to access property 'document'
    IE9报错:    SCRIPT5: 拒绝访问

     

    术语:

    1. CORS    Cross-Origin-Resource-Sharing. (跨域资源共享)  

    2. ACAO    Access-Control-Allow-Origin

     

    解决方案:

    1. 如果都属于同一个域名,但子域不同时,都设置document.domain;即可相互访问;

    2. JSONP通信

    // jQuery JSONP
    var def = $.ajax({
        url:    "http://nuomi.com/test/request/page/jsonp0.jsp",
        dataType:   "jsonp",
        //jsonp:  "cbNameFlag",
        jsonpCallback:  "cbNameTest"
    }).done(function(data, textStatus, jqXHR ){
        console.log("Access done:", arguments, data.info);
    }).fail(function( jqXHR, textStatus, errorThrown){
        console.log("Access fail:", arguments);
    });

     3. Access-Control-Allow-Origin

      这种方案支持两种:

      1) 简单的请求:

      请求方法不支持Put,Delete

      此时Request header会包含:Origin: http://test.nuomi.com;

      期待Response header包含:Access-Control-Allow-Originhttp://test.nuomi.com

       2) Preflight方式的请求:

      这种方式,代码中虽然请求一次,但是实际会请求两次:第一次发送OPTION方法,询问对方是否支持我方某种请求方式(如:GET,POST)?如果第一次进过允许,那么发送第二次请求;否则第二次不再发送;

      第一次请求:

        Request头包括:  OriginAccess-Control-Request-MethodAccess-Control-Request-Headers(optional),

        Response头包括: Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers

         如图所示:

      第二次请求:

        直接用代码中的方法发送(PUT、DELETE),然后得到结果;

       从"6. CORS tutorial"转载的流程如下:

    4. postMessage解决跨域问题,支持IE9及以上;

    /* 外面页面的script */
    function msgHandler(e){
      console.log("Outer message:", e);
    }
    
    if(window.addEventListener){
      window.addEventListener("message", msgHandler, false);
    }else{
      window.attachEvent("message", msgHandler);
    }
    
    // 待加载后发送
    $("#iframe1").on("load", function(e){
      console.info("Iframe onLoad:", e);
      $("#iframe1")[0].contentWindow.postMessage("Data from outer, repects 'the structured clone algorithm. '", "*");
    });
     1 /* 里面页面的script */
     2 function msgHandler(e){
     3     console.log("Inner message:", e);
     4 }
     5 
     6 if(window.addEventListener){
     7     window.addEventListener("message", msgHandler, false);
     8 }else{
     9     window.attachEvent("message", msgHandler);
    10 }
    11 window.parent.postMessage("Data from inner to outer.", "*");

    CORS:

      全称是跨域资源共享(Corss Origin Resource Sharing), 于2014年1月已经成为CORS W3C标准。里面增加了预请求Preflight以支持更广范围的场景。

      常见的头信息包括:

      Request Headers:

      Origin、Access-Control-Request-Method、Access-Control-Request-Headers

      Response Headers:

      1. 允许向该服务器提交请求的URI

      Access-Control-Allow-Origin: <origin> | *

      2. 浏览器允许访问的服务器的头信息的白名单

      Access-Control-Expose-Headers: ..., ...

      3. 请求有效期(单位:秒):

      Access-Control-Max-Age: <seconds>

      4. 允许的请求方法:

      Access-Control-Allow-Methods

      5. 实际的请求中,可以使用的自定义HTTP请求头

      Access-Control-Allow-Headers

      6. 告知客户端,当请求XHR的withCredientials属性是true的时候,响应是否可以被得到。(从而使得下一次请求时,上一次的Cookies可以随着请求发送

      Access-Control-Allow-Credentials

      例子:  withCredential   without credential

      

    参考资料:

    1. Same-origin policy      https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Changing_origin

    2. document.domain      https://developer.mozilla.org/en-US/docs/Web/API/document.domain

    3. HTML <iframe> Element   https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe

    4. window.postMessage    https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage 

    5. Allow CORS          https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

    6. CORS tutorial         http://www.html5rocks.com/en/tutorials/cors/ 

    XSS:

       全称是跨站脚本攻击(Cross Site Scripting),通过在用户浏览某个存在XSS漏洞的站点时,执行特定的脚本或者第三方站点的脚本,从而可以用户sessionid等之类的安全信息。

       这类攻击常被分为两类:

       1. 非持久型xss攻击:  在URL中通过参数嵌入转义的script脚本来;

       2. 存储型XSS攻击:    通过表单提交等方式,在字段中嵌入脚本内容,并存入到后端数据库中;待其他用户浏览时影响更多的用户。

       预防方式:对字段内容进行转义,禁止:<script>之类的内容在前后HTTP中传输;

    Session、Cookie:

      Session保存在服务器端,JAVA EE API写到:

      request.getSession(boolean) 参数为true时,如果不存在则新建一个Session;

      session.getId() 可以获取到唯一标识;

      session.isNew() 判断此时客户端是否用过|知道此session;如果客户端禁用Cookie则isNew()一直返回true;

      session.invalidate() 失效session。

      个人理解:session在server端新建后,会通过response.addCookie()方法在cookie中添加sessionid,否则此后server端怎么识别该客户端呢?

      Cookie保存于浏览器,里面会保存session信息,如果浏览器禁用Cookie,可以在URL或者Form中添加session字段;

  • 相关阅读:
    mysql 索引
    redis持久化
    redis发布订阅
    django 信号
    paramiko模块
    23种设计模式python实现
    几种浏览器存储数据的方式
    关于传参
    对字符串里的四则运算进行计算2020/10/12
    动手动脑2020/10/9
  • 原文地址:https://www.cnblogs.com/diydyq/p/4078689.html
Copyright © 2011-2022 走看看