亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > JavaScript > 正文

深入淺析同源策略和跨域訪問

2024-05-06 16:25:17
字體:
來源:轉載
供稿:網友
同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響??梢哉fWeb是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現
 

1. 什么是同源策略 

    理解跨域首先必須要了解同源策略。同源策略是瀏覽器上為安全性考慮實施的非常重要的安全策略。

    何謂同源:

        URL由協議、域名、端口和路徑組成,如果兩個URL的協議、域名和端口相同,則表示他們同源。

   同源策略:

        瀏覽器的同源策略,限制了來自不同源的"document"或腳本,對當前"document"讀取或設置某些屬性。 (白帽子講web安全[1])

        從一個域上加載的腳本不允許訪問另外一個域的文檔屬性。

    舉個例子:

        比如一個惡意網站的頁面通過iframe嵌入了銀行的登錄頁面(二者不同源),如果沒有同源限制,惡意網頁上的javascript腳本就可以在用戶登錄銀行的時候獲取用戶名和密碼。

    在瀏覽器中,<script>、<img>、<iframe>、<link>等標簽都可以加載跨域資源,而不受同源限制,但瀏覽器限制了JavaScript的權限使其不能讀、寫加載的內容。

    另外同源策略只對網頁的HTML文檔做了限制,對加載的其他靜態資源如javascript、css、圖片等仍然認為屬于同源。

    代碼示例(http://localhost:8080/和http://localhost:8081由于端口不同而不同源):

http://localhost:8080/test.html     <html>       <head><title>test same origin policy</title></head>       <body>         <iframe id="test" src="http://localhost:8081/test2.html"></iframe>         <script type="text/javascript">           document.getElementById("test").contentDocument.body.innerHTML = "write somthing";         </script>       </body>     </html> http://localhost:8081/test2.html     <html>       <head><title>test same origin policy</title></head>       <body>         Testing.       </body>     </html> 

    在Firefox中會得到如下錯誤

        Error: Permission denied to access property 'body'

    Document對象的domain屬性存放著裝載文檔的服務器的主機名,可以設置它。
    例如來自"blog.csdn.net"和來自"bbs.csdn.net"的頁面,都將document.domain設置為"csdn.net",則來自兩個子域名的腳本即可相互訪問。
    出于安全的考慮,不能設置為其他主domain,比如http://www.csdn.net/不能設置為sina.com

2. Ajax跨域

    Ajax (XMLHttpRequest)請求受到同源策略的限制。

    Ajax通過XMLHttpRequest能夠與遠程的服務器進行信息交互,另外XMLHttpRequest是一個純粹的Javascript對象,這樣的交互過程,是在后臺進行的,用戶不易察覺。

    因此,XMLHTTP實際上已經突破了原有的Javascript的安全限制。

    舉個例子:

        假設某網站引用了其它站點的javascript,這個站點被compromise并在javascript中加入獲取用戶輸入并通過ajax提交給其他站點,這樣就可以源源不斷收集信息。

        或者某網站因為存在漏洞導致XSS注入了javascript腳本,這個腳本就可以通過ajax獲取用戶信息并通過ajax提交給其他站點,這樣就可以源源不斷收集信息。

   如果我們又想利用XMLHTTP的無刷新異步交互能力,又不愿意公然突破Javascript的安全策略,可以選擇的方案就是給XMLHTTP加上嚴格的同源限制。

   這樣的安全策略,很類似于Applet的安全策略。IFrame的限制還僅僅是不能訪問跨域HTMLDOM中的數據,而XMLHTTP則根本上限制了跨域請求的提交。(實際上下面提到了CORS已經放寬了限制)

   隨著Ajax技術和網絡服務的發展,對跨域的要求也越來越強烈。下面介紹Ajax的跨域技術。    

2.1 JSONP

    JSONP技術實際和Ajax沒有關系。我們知道<script>標簽可以加載跨域的javascript腳本,并且被加載的腳本和當前文檔屬于同一個域。因此在文檔中可以調用/訪問腳本中的數據和函數。如果javascript腳本中的數據是動態生成的,那么只要在文檔中動態創建<script>標簽就可以實現和服務端的數據交互。

    JSONP就是利用<script>標簽的跨域能力實現跨域數據的訪問,請求動態生成的JavaScript腳本同時帶一個callback函數名作為參數。其中callback函數本地文檔的JavaScript函數,服務器端動態生成的腳本會產生數據,并在代碼中以產生的數據為參數調用callback函數。當這段腳本加載到本地文檔時,callback函數就被調用。

    第一個站點的測試頁面(http://localhost:8080/test.html): 

<script src="http://localhost:8081/test_data.js">   <script>     function test_handler(data) {       console.log(data);     } </script> 

    服務器端的Javascript腳本(http://localhost:8081/test_data.js):

test_handler('{"data": "something"}');

    為了動態實現JSONP請求,可以使用Javascript動態插入<script>標簽:

<script type="text/javascript">     // this shows dynamic script insertion     var script = document.createElement('script');     script.setAttribute('src', url);     // load the script     document.getElementsByTagName('head')[0].appendChild(script);  </script> 

        JSONP協議封裝了上述步驟,jQuery中統一是現在AJAX中(其中data type為JSONP):
    http://localhost:8080/test?callback=test_handler

    為了支持JSONP協議,服務器端必須提供特別的支持[2],另外JSONP只支持GET請求。

2.2 Proxy

    使用代理方式跨域更加直接,因為SOP的限制是瀏覽器實現的。如果請求不是從瀏覽器發起的,就不存在跨域問題了。

    使用本方法跨域步驟如下:

    1. 把訪問其它域的請求替換為本域的請求

    2. 本域的請求是服務器端的動態腳本負責轉發實際的請求
    各種服務器的Reverse Proxy功能都可以非常方便的實現請求的轉發,如Apache httpd + mod_proxy。

    Eg.

    為了通過Ajax從http://localhost:8080訪問http://localhost:8081/api,可以將請求發往http://localhost:8080/api。

    然后利用Apache Web服務器的Reverse Proxy功能做如下配置:

        ProxyPass /api http://localhost:8081/api

2.3 CORS

2.3.1 Cross origin resource sharing

       “Cross-origin resource sharing (CORS) is a mechanism that allows a web page to make XMLHttpRequests to another domain. Such "cross-domain" requests would otherwise be forbidden by web browsers, per the same origin security policy. CORS defines a way in which the browser and the server can interact to determine whether or not to allow the cross-origin request. It is more powerful than only allowing same-origin requests, but it is more secure than simply allowing all such cross-origin requests.” ----Wikipedia[3]

   通過在HTTP Header中加入擴展字段,服務器在相應網頁頭部加入字段表示允許訪問的domain和HTTP method,客戶端檢查自己的域是否在允許列表中,決定是否處理響應。

   實現的基礎是JavaScript不能夠操作HTTP Header。某些瀏覽器插件實際上是具有這個能力的。

   服務器端在HTTP的響應頭中加入(頁面層次的控制模式):

   Access-Control-Allow-Origin: example.com
   Access-Control-Request-Method: GET, POST
   Access-Control-Allow-Headers: Content-Type, Authorization, Accept, Range, Origin
   Access-Control-Expose-Headers: Content-Range
   Access-Control-Max-Age: 3600

   多個域名之間用逗號分隔,表示對所示域名提供跨域訪問權限。"*"表示允許所有域名的跨域訪問。

   客戶端可以有兩種行為:

   1. 發送OPTIONS請求,請求Access-Control信息。如果自己的域名在允許的訪問列表中,則發送真正的請求,否則放棄請求發送。

   2. 直接發送請求,然后檢查response的Access-Control信息,如果自己的域名在允許的訪問列表中,則讀取response body,否則放棄。

   本質上服務端的response內容已經到達本地,JavaScript決定是否要去讀取。

  Support: [Javascript Web Applications]  * IE >= 8 (需要安裝caveat)  * Firefox >= 3  * Safari 完全支持  * Chrome 完全支持  * Opera 不支持

 2.3.2 測試

   測試頁面http://localhost:8080/test3.html使用jquery發送Ajax請求。

<html>     <head><title>testing cross sop</title></head>     <body>       Testing.       <script src="jquery-2.0.0.min.js"></script>       <script type='text/javascript'>         $.ajax({           url: 'http://localhost:8000/hello',           success: function(data) {             alert(data);           },           error: function() {             alert('error');           }         });       </script>     </body> </html> 

    測試Restful API(http://localhost:8000/hello/{name})使用bottle.py來host。

  from bottle import route, run, response  @route('/hello')  def index():    return 'Hello World.'  run(host='localhost', port=8000)

    測試1:

        測試正常的跨域請求的行為。

    測試結果:

        1. 跨域GET請求已經發出,請求header中帶有
            Origin    http://localhost:8080
        2. 服務器端正確給出response
        3. Javascript拒絕讀取數據,在firebug中發現reponse為空,并且觸發error回調

    測試2:

        測試支持CORS的服務器的跨域請求行為。
        對Restful API做如下改動,在response中加入header:
             def index():
                #Add CORS header#
                response.set_header("Access-Control-Allow-Origin", "http://localhost:8080")
                return 'Hello World.'
  

  測試結果:

        1. 跨域GET請求已經發出,請求header中帶有
            Origin    http://localhost:8080
        2. 服務器端正確給出response
        3. 客戶端正常獲取數據

    測試3:

        測試OPTIONS請求獲取CORS信息。
        對客戶端的Ajax請求增加header:       

$.ajax({      url: 'http://localhost:8000/hello',      headers: {'Content-Type': 'text/html'},      success: function(data) {        alert(data);      },      error: function() {        alert('error');      }    }); 

        對Restful API做如下改動:

   @route('/hello', method = ['OPTIONS', 'GET'])      def index():        if request.method == 'OPTIONS':          return ''        return 'Hello World.'

    測試結果:

    1. Ajax函數會首先發送OPTIONS請求
    2. 針對OPTIONS請求服務器
    3. 客戶端發現沒有CORS header后不會發送GET請求

    測試4:

        增加服務器端對OPTIONS方法的處理。
        對Restful API做如下改動:

 @route('/hello', method = ['OPTIONS', 'GET'])      def index():        response.headers['Access-Control-Allow-Origin'] = 'http://localhost:8080'        response.headers['Access-Control-Allow-Methods'] = 'GET, OPTIONS'        response.headers['Access-Control-Allow-Headers'] = 'Origin, Accept, Content-Type'        if request.method == 'OPTIONS':          return ''        return 'Hello World.'

    測試結果:

        1. Ajax函數會首先發送OPTIONS請求
        2. 針對OPTIONS請求服務器
        3. 客戶端匹配CORS header中的allow headers and orgin后會正確發送GET請求并獲取結果

      測試發現,Access-Control-Allow-Headers是必須的。

   CORS協議提升了Ajax的跨域能力,但也增加了風險。一旦網站被注入腳本或XSS攻擊,將非常方便的獲取用戶信息并悄悄傳遞出去。

4. Cookie 同源策略

    Cookie中的同源只關注域名,忽略協議和端口。所以https://localhost:8080/和http://localhost:8081/的Cookie是共享的。

5. Flash/SilverLight跨域

    瀏覽器的各種插件也存在跨域需求。通常是通過在服務器配置crossdomain.xml[4],設置本服務允許哪些域名的跨域訪問。
    客戶端會首先請求此文件,如果發現自己的域名在訪問列表里,就發起真正的請求,否則不發送請求。

 <?xml version="1.0"?>      <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">      <cross-domain-policy>      <allow-access-from domain="*"/>      <allow-http-request-headers-from domain="*" headers="*"/>    </cross-domain-policy>

    通常crossdomain.xml放置在網站根目錄。

6. 總結 

    互聯網的發展催生了跨域訪問的需求,各種跨域方法和協議滿足了需求但也增加了各種風險。尤其是XSS和CSRF等攻擊的盛行也得益于此。

    了解這些技術背景有助于在實際項目中熟練應用并規避各種安全風險。



注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲成人国产精品| 久久艳片www.17c.com| 国产精品一区二区久久精品| 伊人久久免费视频| 亚洲的天堂在线中文字幕| 中文字幕亚洲天堂| 久久在线观看视频| www.日韩不卡电影av| 欧美午夜精品久久久久久浪潮| 欧美日韩中文字幕日韩欧美| 一本色道久久综合狠狠躁篇的优点| 国产精品久久久久7777婷婷| 久久精品一偷一偷国产| 国产午夜精品全部视频播放| 欧美巨乳在线观看| 亚洲第一精品夜夜躁人人爽| 亚洲字幕一区二区| 亚洲成人激情小说| 狠狠躁夜夜躁久久躁别揉| 538国产精品一区二区在线| 亚洲天堂av在线免费| 精品视频在线播放免| 久久久久成人精品| 日韩a**站在线观看| 亚洲天天在线日亚洲洲精| 69久久夜色精品国产69乱青草| 亚洲成人黄色网址| 亚洲视频在线免费看| 亚洲精品在线91| 69国产精品成人在线播放| 国产精品福利久久久| 久久99久国产精品黄毛片入口| 亚洲人线精品午夜| 久久久亚洲成人| 97视频免费观看| 亚洲天堂网站在线观看视频| 欧美色xxxx| 欧美精品中文字幕一区| 亚洲午夜女主播在线直播| 668精品在线视频| 欧美精品在线免费观看| 最近中文字幕2019免费| 久久99热精品这里久久精品| 欧美乱大交xxxxx另类电影| 成人在线精品视频| 欧美精品一区在线播放| 久国内精品在线| 欧美日韩免费观看中文| 久久久久久久影视| 97精品国产97久久久久久| 亚洲美女久久久| 97香蕉久久夜色精品国产| 国产不卡精品视男人的天堂| 2019国产精品自在线拍国产不卡| 久久夜精品va视频免费观看| 91在线视频导航| 欧美一区二三区| 亚洲欧美激情视频| 成人字幕网zmw| 日韩中文字幕精品视频| 国产欧美一区二区三区在线| 欧美激情乱人伦| 91在线观看欧美日韩| 日韩国产激情在线| 亚洲资源在线看| 亚洲一区二区三区四区视频| 日韩一区在线视频| 国产精品爽爽爽爽爽爽在线观看| 国模吧一区二区三区| 欧美成人免费全部观看天天性色| 97久久久免费福利网址| 日韩av大片免费看| 亚洲国产精品福利| 国产精品一区二区三区毛片淫片| 欧亚精品中文字幕| 欧美久久久精品| 92国产精品久久久久首页| 北条麻妃一区二区在线观看| 欧美精品第一页在线播放| 亚洲成人精品久久久| 欧美高清一级大片| 国产一区二区三区在线| 91久久在线播放| 国产最新精品视频| 91久久精品美女高潮| 国产视频在线一区二区| 在线观看欧美日韩| 国产一区二区激情| 国产精品麻豆va在线播放| 国产日韩精品一区二区| 国产成人精品久久| 欧美性生交xxxxx久久久| 久久久av网站| 成人av电影天堂| 91精品国产高清自在线| 精品国产一区二区三区久久狼黑人| y97精品国产97久久久久久| 奇米成人av国产一区二区三区| 91亚洲va在线va天堂va国| 欧美成人激情图片网| 懂色aⅴ精品一区二区三区蜜月| 欧美有码在线观看视频| 欧美激情免费视频| 中文字幕精品www乱入免费视频| 国产视频福利一区| 久久久久久国产| 色视频www在线播放国产成人| 亚洲一区亚洲二区| 久久91精品国产91久久久| 原创国产精品91| 日韩精品黄色网| 国产精品视频一区二区三区四| 97av在线播放| 国产精品毛片a∨一区二区三区|国| 国产一区二区三区在线播放免费观看| 91青草视频久久| 欧美黄色小视频| 亚洲一区二区三区乱码aⅴ蜜桃女| 奇米四色中文综合久久| 激情亚洲一区二区三区四区| 亚洲三级黄色在线观看| 狠狠久久亚洲欧美专区| 成人黄色片在线| 国产精品视频26uuu| 九色精品美女在线| 亚洲自拍偷拍视频| 在线亚洲男人天堂| 亚洲国产成人精品电影| 国产亚洲精品美女| 精品久久久久久中文字幕| 久久人人爽人人爽人人片av高请| 久久久久亚洲精品| 久久久久久久国产精品| 国产一级揄自揄精品视频| 91精品久久久久久久久中文字幕| 国产高清视频一区三区| 国产精品久久久久久一区二区| 26uuu久久噜噜噜噜| 欧美精品激情在线观看| 国产精品久久久久久久久久久久久久| 正在播放欧美一区| 久久九九有精品国产23| 午夜精品久久久久久久99黑人| 亚洲精品suv精品一区二区| 久久在线免费观看视频| 欧美亚洲第一区| 精品一区二区三区四区| 欧美在线观看网址综合| 日本亚洲欧美三级| 国产日韩欧美日韩大片| 欧美激情图片区| 国产一区玩具在线观看| 久久亚洲欧美日韩精品专区| 国内精品久久久| 国产精品一区二区电影| 91精品久久久久久久久久久久久久| 国产成人亚洲综合青青| 欧美久久精品一级黑人c片| 日韩美女免费观看| 久久国产精品视频| 性欧美长视频免费观看不卡| 日本欧美一级片| 九九久久久久99精品| 亚洲综合精品一区二区|