HTTP與IIS知識點

HTTP

TCP/IP

使用的網絡是在TCP/IP協議族的基礎上運做的。HTTP屬於它內部的一個子集。javascript

協議:計算機與設備要互相通訊,雙方就必須基於相同的方法。這種規則稱爲協議(protocol) html

分層管理

TCP/IP協議族按層次分別分爲4層:應用層、傳輸層、網絡層、數據鏈路層。分層的優勢是:單一職責和靈活變更。java

應用層:決定向用戶提供應用服務時通訊的活動,例如:FTP、DNS。HTTP協議也處於該層。jquery

傳輸層:提供處於網絡鏈接中的兩臺計算機之間的數據傳輸。例如:TCP、UDPgit

網絡層:用來處理網絡上流動的數據包,規定了經過怎樣的路徑到達對方計算機。例如:IP協議web

鏈路層:用來處理鏈接網絡的硬件部分,包括操做系統、硬件設備驅動、光纖等物理部件。算法

發送端順序從上往下,接收端順序從下往上。數據庫

舉例:json

首先客戶端在應用層發出一個HTTP請求。傳輸層把收到的HTTP報文進行分割,並標記序號和端口號發給網絡層。api

網絡層(IP協議)增長做爲通訊目的地的MAC地址後轉發給鏈路層

發送端層與層之間傳輸數據時,每通過一層則會打上該層所屬的首部信息。接收端則通過每層都會把對應信息消除。

IP傳輸

IP協議的做用是把各類數據包傳送給對方,其中有兩個條件必須知足:IP地址和MAC地址。

IP地址指明節點被分配到的地址,MAC地址是指網卡所屬的固定地址。IP可變,MAC不可變。

IP間的通訊依賴MAC地址,一般是通過多臺計算機和網絡設備中轉才能鏈接到對方。

在中轉時,會利用下一站中轉設備的MAC地址來搜索下一個中轉目標。會採用APR協議。

ARP是一種用以解析地址的協議,根據通訊方的IP地址就能夠反查出對應的MAC地址。

TCP協議

TCP位於傳輸層,提供可靠的字節流服務。指將大塊數據分割成以報文段爲單位的數據包進行管理。

TCP協議爲了更容易傳送大數據才把數據分割,並且TCP協議可以確認數據最終是否送達到對方。

三次握手

爲了準確傳送數據,TCP協議採用了三次握手策略。

1. 發送端首先發送一個帶有SYN標誌的數據包給對方。

2. 接收端收到後,回傳一個帶有SYN/ACK標誌的數據包傳達確認信息。

3. 發送端在回傳一個帶ACK標誌的數據包,表示握手結束。

DNS域名解析

跟HTTP協議同樣,處於應用層。DNS協議經過域名查找IP地址或從IP地址反查域名。

URI:統一資源標識符。由某個協議方案表示的資源定位標識符

URL:統一資源定位符

Uniform:規定統一的格式方便處理多種不一樣類型的資源,不用根據上下文環境來識別資源指定的訪問方式。

Resource:字符串標誌。資源定義是可標識的任何東西。文檔、圖形、服務

Identifier:可標識的對象。也稱爲標識符。

採用HTTP協議是,Uniform 就是http。URI用字符串標識某一互聯網資源,URL表示資源的地址是URI的子集。

格式:http://(協議名)user:pass(登陸信息)@www.example.jp:80(服務器地址和端口號)/index.html(文件路徑)?uid=1(查詢字符串)@ch1(片斷標識符,例如錨點)

HTTP通訊

進行HTTP協議通訊時,好比一端是客戶端,另外一端是服務端。一定是客戶端發送請求,服務端回覆響應。

無狀態協議

HTTP是不保存狀態的協議:即無狀態協議。HTTP協議自身不對請求和響應之間的通訊狀態進行保存。

持久連接

持久連接特色是:只要任意一端沒有明確提出斷開連接,則保持TCP連接狀態。用來避免頻繁建立連接使服務器壓力增大。

HTTP/1.1中全部的連接默認都是持久連接。

管線化 

持久鏈接使多數請求以管線化進行發送。能夠作到同時並行發送多個請求,不須要一個接一個地等待響應。

壓縮傳輸

HTTP協議中有一種內容編碼的功能,指明應用在實體內容上的編碼格式,並保存實體信息原樣壓縮。

內容編碼後的實體由客戶端接收並負責解碼。

經常使用的內容編碼有如下幾種:

1. gzip(GNU zip)

2.compress(UNIX系統的標準壓縮)

3.deflate(zlib)

4.identity(不進行編碼)

分塊傳輸

HTTP通訊中編碼實體資源還沒有徹底傳輸完成以前,瀏覽器沒法顯示請求頁面。

在傳輸大容量數據時,經過把數據分割成多塊,可以讓瀏覽器逐步顯示頁面。

把實體主體分塊的功能稱爲分塊傳輸編碼。

分塊傳輸編碼會將實體主體分紅多個部分快,每一塊用十六進制來標記塊的大小,最後一塊使用0來標記。

使用分塊傳輸編碼的實體主體會由接受的客戶端負責解碼,恢復到編碼前的實體主體。

HTTP/1.1中存在一種稱爲傳輸編碼的機制,它能夠在通訊時按某種編碼方式傳輸,但只定義做用於分塊傳輸編碼中。

MIME 

MIME機制,容許郵件處理文本、圖片、視頻等多個不一樣類型的數據。例如:圖片等二進制數據以ASCII碼字符串編碼的方式,

就是利用MIME來描述標記數據類型。而在MIME擴展中會使用一種稱爲多部分對象集合的方法,來容納多份不一樣類型的數據。

分流下載

若是下載過程當中網絡中斷,就必須從頭開始。爲了解決問題,須要一種可恢復的機制。能夠從以前下載中斷處恢復下載。

要實現該功能須要指定下載實體範圍。指定範圍發送的請求叫作範圍請求。

對一份10000字節大小的資源,若是使用範圍請求,能夠只請求5001-10000字節內的資源。

執行範圍請求時,會用到首部資源Range來指定資源的byte範圍。例如:

Range:bytes=5001-10000 (從5000-10000)

Range:bytes=5001- (從5001字節以後所有的)

Range:bytes=-3000,5000-7000 (從開始到3000和5000-7000字節)

針對範圍請求,響應會返回 206(部份內容)的響應報文。對於多重範圍的範圍請求,響應在首部字段。

若是沒法響應範圍請求,則會返回狀態碼200和完整的實體內容。

內容協商

當瀏覽器的默認語言爲英文時,訪問相同的URI和Web頁面則會顯示對應的英語版的頁面。

指客戶端和服務端就響應的資源內容進行交涉,而後提供給客戶端最爲適合的資源。

內容協商會以響應資源的語言、字符集、編碼方式等做爲判斷的基準。

狀態碼

狀態碼中第一位指定了響應類別,後兩位無分類。響應類別有以下5中。

1XX:接受的請求正在處理

2XX:請求正常處理完畢

3XX:須要進行附加操做已完成請求

4XX:服務器沒法處理請求

5XX:服務器處理請求出錯

常用的有14中狀態碼

2XX:請求被正常處理了

200 OK

表示從客戶端發來的請求被正常處理了

204 No Content

表明服務器接收的請求以成功處理,但在返回的響應報文中不含實體的主體部分。

好比:發送請求處理後,返回204響應,瀏覽器不發生更新。

206 Partial Content

客戶端進行了範圍請求,而服務器成功執行了這部分的Get請求。

響應報文中包含有Content-Range 指定範圍的實體內容。

3XX:須要執行某些特殊的處理以正確處理請求

301 Moved Permanently

永久性重定向,表示請求資源已被分配了新的URI。

302 Found

臨時性重定向。該狀態碼錶示請求的資源已被分配了新的URI。

303 See Other

請求對應的資源存在着另外一個URI,應使用Get方法定義獲取請求的資源。

304 Not Modified

不包含任何響應的主體部分。

307 Temporary Redirect

臨時重定向,跟302相比,不會從POST變成GET。

4XX:客戶端錯誤

400 Bad Request

請求表文中存在語法錯誤。需修改請求的內容後再次發送請求。

401 Unauthorized

用戶認證失敗,沒有經過HTTP認證。

403 Forbidden

對請求資源的訪問被服務器拒絕了。服務器沒有必要給出拒絕的詳細理由。

未獲取文件系統的訪問受權,或從未受權的地址發送IP地址試圖訪問。都是403的緣由。

404 Not Found

沒法找到請求的資源

5XX:服務器自己發生錯誤

500 Internal Server Error

服務器端在執行請求時發生了錯誤,也有多是Web應用存在bug或某些臨時的故障。

503 Service Unavailable

服務器出超負載或進行停機維護

通訊數據轉發程序

HTTP通訊時,除客戶端和服務器外,還有一些用於通訊數據轉發的程序。

代理

一種有轉發功能的應用程序,扮演了位於服務器和客戶端「中間人」角色。接受由客戶端發送的請求並轉發給服務器。

網關

網關是轉發其餘服務器通訊數據的服務器,接受從客戶端發來的請求。對請求進行處理。

隧道

隧道是在相隔甚遠的客戶端和服務器二者之間進行中轉,並保存雙方通訊鏈接的應用程序。

緩存

緩存指代理服務器或客戶端本地磁盤內保存的資源副本。利用緩存可減小對源服務器的訪問。

緩存服務器是代理服務器的一種,並歸類在緩存代理類型中。當代理轉發從服務器返回的響應時,會保存一份資源的副本

優點:利用緩存可避免屢次從源服務器轉發資源,所以客戶端可就近從緩存服務器上獲取資源。

有效期

當趕上源服務器上的資源更新時,若是仍是使用不變的緩存,那就會變成返回更新前的舊資源了。

所以會因客戶端的要求,花奴才能的有效期等因素。源服務器肯定緩存的有效性。如失效則會重新獲取。

客戶端的緩存

緩存還能夠存在客戶端瀏覽器中。若是有效就沒必要向服務器請求相同的資源了,能夠從本地直接讀取。

當判斷緩存國旗後,服務器肯定資源的有效性。若瀏覽器緩存失效,瀏覽器會再次請求緩存。

HTTP頭

HTTP頭分爲4種

1.通用首部字段

請求報文和響應報文兩方都會使用的首部。

2.請求首部字段

補充了請求的附加內容、客戶端信息、響應內容相關優先級等信息

3.響應首部字段

補充了響應的附加內容,要求客戶端附加額外的內容信息。

4.實體首部字段

針對請求報文和響應報文的實體部分使用的首部。補充了資源內容、更新時間等於實體有關的信息。

詳細列表:HTTP頭明細說明

HTTPS

1、做用

不使用SSL/TLS的HTTP通訊,就是不加密的通訊。全部信息明文傳播,帶來了三大風險。

(1) 竊聽風險(eavesdropping):第三方能夠獲知通訊內容。

(2) 篡改風險(tampering):第三方能夠修改通訊內容。

(3) 冒充風險(pretending):第三方能夠冒充他人身份參與通訊。

SSL/TLS協議是爲了解決這三大風險而設計的,但願達到:

(1) 全部信息都是加密傳播,第三方沒法竊聽。

(2) 具備校驗機制,一旦被篡改,通訊雙方會馬上發現。

(3) 配備身份證書,防止身份被冒充。

互聯網是開放環境,通訊雙方都是未知身份,這爲協議的設計帶來了很大的難度。並且,協議還必須可以經受全部匪夷所思的攻擊,這使得SSL/TLS協議變得異常複雜。

2、歷史

互聯網加密通訊協議的歷史,幾乎與互聯網同樣長。

1994年,NetScape公司設計了SSL協議(Secure Sockets Layer)的1.0版,可是未發佈。

1995年,NetScape公司發佈SSL 2.0版,很快發現有嚴重漏洞。

1996年,SSL 3.0版問世,獲得大規模應用。

1999年,互聯網標準化組織ISOC接替NetScape公司,發佈了SSL的升級版TLS 1.0版。

2006年和2008年,TLS進行了兩次升級,分別爲TLS 1.1版和TLS 1.2版。最新的變更是2011年TLS 1.2的修訂版

目前,應用最普遍的是TLS 1.0,接下來是SSL 3.0。可是,主流瀏覽器都已經實現了TLS 1.2的支持。

TLS 1.0一般被標示爲SSL 3.1,TLS 1.1爲SSL 3.2,TLS 1.2爲SSL 3.3。

3、基本的運行過程

SSL/TLS協議的基本思路是採用公開密鑰加密法,也就是說,客戶端先向服務器端索要公鑰,而後用公鑰加密信息,服務器收到密文後,用本身的私鑰解密。

可是,這裏有兩個問題。

(1)如何保證公鑰不被篡改?

解決方法:將公鑰放在數字證書中。只要證書是可信的,公鑰就是可信的。數字證書認證機構CA,雙方均可信賴的第三方機構。

使用CA之後的流程變爲:

1.服務器向機構提出申請,機構判明申請者身份後,會對已申請的公開密鑰證書作數字簽名,而後分配這個已簽名的公開密鑰。

2.服務器會將這份由數字證書認證機構頒發的公鑰證書發給客戶端,並進行公共密鑰加密方式通訊。

3.接到證書的客戶端可以使用數字證書認證機構的公開密鑰,對那證書上的簽名進行驗證。

公開密鑰轉交給客戶端,是一件很困難的事情,所以多數瀏覽器開發商會在內部植入經常使用的認證機關的公開密鑰。

(2)公鑰加密計算量太大,如何減小耗用的時間?

解決方法:每一次對話(session),客戶端和服務器端都生成一個"對話密鑰"(session key),用它來加密信息。因爲"對話密鑰"是對稱加密,因此運算速度很是快,而服務器公鑰只用於加密"對話密鑰"自己,這樣就減小了加密運算的消耗時間。

所以,SSL/TLS協議的基本過程是這樣的:

(1) 客戶端向服務器端索要並驗證公鑰。

(2) 雙方協商生成"對話密鑰"。

(3) 雙方採用"對話密鑰"進行加密通訊。

上面過程的前兩步,又稱爲"握手階段"(handshake)。

4、握手階段的詳細過程

"握手階段"涉及四次通訊,咱們一個個來看。須要注意的是,"握手階段"的全部通訊都是明文的。

4.1 客戶端發出請求(ClientHello)

首先,客戶端(一般是瀏覽器)先向服務器發出加密通訊的請求,這被叫作ClientHello請求。

在這一步,客戶端主要向服務器提供如下信息。

(1) 支持的協議版本,好比TLS 1.0版。

(2) 一個客戶端生成的隨機數,稍後用於生成"對話密鑰"。

(3) 支持的加密方法,好比RSA公鑰加密。

(4) 支持的壓縮方法。

這裏須要注意的是,客戶端發送的信息之中不包括服務器的域名。也就是說,理論上服務器只能包含一個網站,不然會分不清應該向客戶端提供哪個網站的數字證書。這就是爲何一般一臺服務器只能有一張數字證書的緣由。

對於虛擬主機的用戶來講,這固然很不方便。2006年,TLS協議加入了一個Server Name Indication擴展,容許客戶端向服務器提供它所請求的域名。

4.2 服務器迴應(SeverHello)

服務器收到客戶端請求後,向客戶端發出迴應,這叫作SeverHello。服務器的迴應包含如下內容。

(1) 確認使用的加密通訊協議版本,好比TLS 1.0版本。若是瀏覽器與服務器支持的版本不一致,服務器關閉加密通訊。

(2) 一個服務器生成的隨機數,稍後用於生成"對話密鑰"。

(3) 確認使用的加密方法,好比RSA公鑰加密。

(4) 服務器證書。

除了上面這些信息,若是服務器須要確認客戶端的身份,就會再包含一項請求,要求客戶端提供"客戶端證書"。好比,金融機構每每只容許認證客戶連入本身的網絡,就會向正式客戶提供USB密鑰,裏面就包含了一張客戶端證書。

4.3 客戶端迴應

客戶端收到服務器迴應之後,首先驗證服務器證書。若是證書不是可信機構頒佈、或者證書中的域名與實際域名不一致、或者證書已通過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通訊。

若是證書沒有問題,客戶端就會從證書中取出服務器的公鑰。而後,向服務器發送下面三項信息。

(1) 一個隨機數。該隨機數用服務器公鑰加密,防止被竊聽。

(2) 編碼改變通知,表示隨後的信息都將用雙方商定的加密方法和密鑰發送。

(3) 客戶端握手結束通知,表示客戶端的握手階段已經結束。這一項同時也是前面發送的全部內容的hash值,用來供服務器校驗。

上面第一項的隨機數,是整個握手階段出現的第三個隨機數,又稱"pre-master key"。有了它之後,客戶端和服務器就同時有了三個隨機數,接着雙方就用事先商定的加密方法,各自生成本次會話所用的同一把"會話密鑰"。

至於爲何必定要用三個隨機數,來生成"會話密鑰",dog250解釋得很好:

"無論是客戶端仍是服務器,都須要隨機數,這樣生成的密鑰纔不會每次都同樣。因爲SSL協議中證書是靜態的,所以十分有必要引入一種隨機因素來保證協商出來的密鑰的隨機性。

對於RSA密鑰交換算法來講,pre-master-key自己就是一個隨機數,再加上hello消息中的隨機,三個隨機數經過一個密鑰導出器最終導出一個對稱密鑰。

pre master的存在在於SSL協議不信任每一個主機都能產生徹底隨機的隨機數,若是隨機數不隨機,那麼pre master secret就有可能被猜出來,那麼僅適用pre master secret做爲密鑰就不合適了,所以必須引入新的隨機因素,那麼客戶端和服務器加上pre master secret三個隨機數一同生成的密鑰就不容易被猜出了,一個僞隨機可能徹底不隨機,但是是三個僞隨機就十分接近隨機了,每增長一個自由度,隨機性增長的可不是一。"

此外,若是前一步,服務器要求客戶端證書,客戶端會在這一步發送證書及相關信息。

4.4 服務器的最後迴應

服務器收到客戶端的第三個隨機數pre-master key以後,計算生成本次會話所用的"會話密鑰"。而後,向客戶端最後發送下面信息。

(1)編碼改變通知,表示隨後的信息都將用雙方商定的加密方法和密鑰發送。

(2)服務器握手結束通知,表示服務器的握手階段已經結束。這一項同時也是前面發送的全部內容的hash值,用來供客戶端校驗。

至此,整個握手階段所有結束。接下來,客戶端與服務器進入加密通訊,就徹底是使用普通的HTTP協議,只不過用"會話密鑰"加密內容。

WEB攻擊

Web攻擊分爲兩種:主動攻擊和被動攻擊

主動攻擊:指攻擊者經過訪問Web應用,把攻擊代碼傳入的攻擊模式。例如:SQL注入

被動攻擊:指利用圈套策略執行攻擊代碼的攻擊模式。攻擊者不直接對目標發起攻擊。例如:XSS(跨站腳本攻擊)和CSRF(跨站請求僞造)

步驟大體以下:

1.攻擊者誘導用戶觸發已設置好的陷阱,而陷阱會啓動發送已嵌入攻擊代碼的HTTP請求。

2.當用戶不知不覺中招後,用戶的瀏覽器或郵件客戶端就會觸發這個陷阱。

3.中招後的用戶瀏覽器會把含有攻擊代碼的HTTP請求發送給做爲攻擊目標的Web應用,運行攻擊代碼。

4.存在安全漏洞的Web應用會成爲攻擊者的跳板,可能致使用戶所持的Cookie等我的信息被竊取。

跨站腳本攻擊

Cross-Site Scripting,XSS:是指經過存在安全漏洞的Web網站註冊用戶的瀏覽器運行非法的HTML標籤或JavaScript進行的一種攻擊。

動態建立的HTML部分有可能隱藏着安全漏洞。攻擊者編寫腳本設下陷阱,用戶在本身的瀏覽器上運行時,不當心就會受到攻擊。

攻擊可能形成的影響:

1.利用虛假輸入表單騙取用戶我的信息。

2.利用腳本竊取用戶的Cookie值,被害者在不知情的狀況下,幫助攻擊者發送惡意請求。

3.顯示僞造的文章或圖片。

例如:

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src=" app/bower_components/jquery/dist/jquery.min.js"></script>
    <script type="text/javascript">
        function SaveForm(){
            $("#spName").html($("#txtName").val());
        }
    </script>
</head>
<body>
    姓名:<input type="text" id="txtName" /> <span id="spName"></span>
    <button onclick="SaveForm()">保存</button>
</body>

如上所示,我若是在姓名中輸入:<script>window.open('http://www.baidu.com');</script>。就會執行腳本,進行跳轉。

HTTP頭明細

一般HTTP消息包括客戶機向服務器的請求消息和服務器向客戶機的響應消息。客戶端向服務器發送一個請求,請求頭包含請求的方法、URI、協議版本、以及包含請求修飾符、客戶信息和內容的相似於MIME的消息結構。服務器以一個狀態行做爲響應,相應的內容包括消息協議的版本,成功或者錯誤編碼加上包含服務器信息、實體元信息以及可能的實體內容。

Http協議定義了不少與服務器交互的方法,最基本的有4種,分別是GET、POST、PUT、DELETE。一個URL地址用於描述一個網絡上的資源,而HTTP中的GET、POST、PUT、 DELETE就對應着對這個資源的查、改、增、刪4個操做,咱們最多見的就是GET和POST了。GET通常用於獲取/查詢資源信息,而POST通常用於更新資源信息。

HTTP頭信息解讀

  HTTP的頭域包括通用頭、請求頭、響應頭和實體頭四個部分。每一個頭域由一個域名,冒號(:)和域值三部分組成。

  通用頭部是客戶端和服務器均可以使用的頭部,能夠在客戶端、服務器和其餘應用程序之間提供一些很是有用的通用功能,如Date頭部。

  請求頭部是請求報文特有的,它們爲服務器提供了一些額外信息,好比客戶端但願接收什麼類型的數據,如Accept頭部。

  響應頭部便於客戶端提供信息,好比,客服端在與哪一種類型的服務器進行交互,如Server頭部。

  實體頭部指的是用於應對實體主體部分的頭部,好比,能夠用實體頭部來講明實體主體部分的數據類型,如Content-Type頭部。

HTTP通用頭

  通用頭域包含請求和響應消息都支持的頭域,通用頭域包含緩存頭部Cache-Control、Pragma及信息性頭部Connection、Date、Transfer-Encoding、Update、Via。

  一、Cache-Control

  Cache-Control指定請求和響應遵循的緩存機制。在請求消息或響應消息中設置 Cache-Control並不會修改另外一個消息處理過程當中的緩存處理過程。

  緩存請求指令 (指令:參數:說明)

  • no-cache:無:強制向源服務器再次驗證
  • no-store:無:不緩存請求或響應的任何內容
  • max-age=[秒]:必需:響應的最大Age值(Age值表示緩存壽命時間)
  • max-stale(=[秒]):可省略:接收已過時的響應
  • min-fresh=[秒]:必需:指望在指定時間內的響應仍有效
  • no-transform:無:代理不可更改媒體類型
  • only-if-cached:無:從緩存獲取資源
  • cache-extension:-:新指令標記(token)

    緩存響應指令

  • public:無:可向任意方提供響應的緩存
  • private:可省:僅向特定用戶返回響應
  • no-cache:可省:緩存前必須先肯定其有效性
  • no-store:無:不緩存請求或響應的任何內容
  • no-transform:無:代理不可更改媒體類型
  • must-revalidate:無:可緩存但必須再向源服務器進行確認
  • proxy-revalidate:無:要求中間緩存服務器對緩存的響應進行有效性驗證
  • max-age:響應最大的Age值
  • s-maxage:公共緩存服務器的最大Age值
  • cache-extension:-:新指令標記(token)

  二、Pragma

  Pragma頭域用來包含實現特定的指令,最經常使用的是Pragma:no-cache。在HTTP/1.1協議中,它的含義和Cache- Control:no-cache相同。

  三、Connection

  Connection表示是否須要持久鏈接。若是Servlet看到這裏的值爲「Keep-Alive」,或者看到請求使用的是HTTP 1.1(HTTP 1.1默認進行持久鏈接),它就能夠利用持久鏈接的優勢,當頁面包含多個元素時(例如Applet,圖片),顯著地減小下載所須要的時間。要實現這一點,Servlet須要在應答中發送一個Content-Length頭,最簡單的實現方法是:先把內容寫入ByteArrayOutputStream,而後在正式寫出內容以前計算它的大小。

  Close:告訴WEB服務器或者代理服務器,在完成本次請求的響應後,斷開鏈接,不要等待本次鏈接的後續請求了。

  Keepalive:告訴WEB服務器或者代理服務器,在完成本次請求的響應後,保持鏈接,等待本次鏈接的後續請求。

  Keep-Alive:若是瀏覽器請求保持鏈接,則該頭部代表但願 WEB 服務器保持鏈接多長時間(秒),如Keep-Alive:300。

  四、Date

  Date頭域表示消息發送的時間,服務器響應中要包含這個頭部,由於緩存在評估響應的新鮮度時要用到,其時間的描述格式由RFC822定義。例如,Date:Mon, 31 Dec 2001 04:25:57 GMT。Date描述的時間表示世界標準時,換算成本地時間,須要知道用戶所在的時區。

  五、Trailer

  說明在報文主體後記錄了哪些首部字段,該字段可應用在分塊傳輸編碼時。

  五、Transfer-Encoding

  WEB 服務器代表本身對本響應消息體(不是消息體裏面的對象)做了怎樣的編碼,好比是否分塊(chunked),例如:Transfer-Encoding: chunked

  六、Upgrade

  它能夠指定另外一種可能徹底不一樣的協議,如HTTP/1.1客戶端能夠向服務器發送一條HTTP/1.0請求,其中包含值爲「HTTP/1.1」的Update頭部,這樣客戶端就能夠測試一下服務器是否也使用HTTP/1.1了。

  七、Via

  列出從客戶端到 OCS 或者相反方向的響應通過了哪些代理服務器,他們用什麼協議(和版本)發送的請求。

  當客戶端請求到達第一個代理服務器時,該服務器會在本身發出的請求裏面添加 Via 頭部,並填上本身的相關信息,當下一個代理服務器 收到第一個代理服務器的請求時,會在本身發出的請求裏面複製前一個代理服務器的請求的Via頭部,並把本身的相關信息加到後面,以此類推,當 OCS 收到最後一個代理服務器的請求時,檢查 Via 頭部,就知道該請求所通過的路由。例如:Via:1.0 236-81.D07071953.sina.com.cn:80 (squid/2.6.STABLE13)

  七、Warning

  Warning首部是從HTTP/1.0的響應首部演變過來的,告知用戶一些與緩存相關的警告。一共7種警告:

  1. 110:代理返回已過時的資源
  2. 111:代理再驗證資源有效性時失敗
  3. 112:代理與互聯網鏈接被故意切斷
  4. 113:響應的使用期超過24小時
  5. 119:任意的警告內容
  6. 214:代理對內容編碼或媒體類型等執行了某些處理
  7. 299:持久性的任意警告內容

HTTP請求頭

  請求頭用於說明是誰或什麼在發送請求、請求源於何處,或者客戶端的喜愛及能力。服務器能夠根據請求頭部給出的客戶端信息,試着爲客戶端提供更好的響應。請求頭域可能包含下列字段Accept、Accept-Charset、Accept- Encoding、Accept-Language、Authorization、From、Host、If-Modified-Since、If-Match、If-None-Match、If-Range、If-Range、If-Unmodified-Since、Max-Forwards、Proxy-Authorization、Range、Referer、User-Agent。對請求頭域的擴展要求通信雙方都支持,若是存在不支持的請求頭域,通常將會做爲實體頭域處理。

  八、Accept

  告訴WEB服務器本身接受什麼介質類型,*/* 表示任何類型,type/* 表示該類型下的全部子類型,type/sub-type。

  例如:Accept:text/plain;q=0.3,text/htm。q表示優先級,範圍是0-1,使用;進行分割。也就是優先給我html。

  九、Accept-Charset

  瀏覽器告訴服務器本身能接收的字符集。

  十、Accept-Encoding

  瀏覽器申明本身接收的編碼方法,一般指定壓縮方法,是否支持壓縮,支持什麼壓縮方法(gzip,deflate)。

  十一、Accept-Language

  瀏覽器申明本身接收的語言。語言跟字符集的區別:中文是語言,中文有多種字符集,好比big5,gb2312,gbk等等。

  十二、Authorization

  當客戶端接收到來自WEB服務器的 WWW-Authenticate 響應時,用該頭部來回應本身的身份驗證信息給WEB服務器。

  1三、If-Match

  若是對象的 ETag 沒有改變,其實也就意味著對象沒有改變,才執行請求的動做,獲取文檔。

  1四、If-None-Match

  若是對象的 ETag 改變了,其實也就意味著對象也改變了,才執行請求的動做,獲取文檔。

  1五、If-Modified-Since

  若是請求的對象在該頭部指定的時間以後修改了,才執行請求的動做(好比返回對象),不然返回代碼304,告訴瀏覽器該對象沒有修改。例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT

  1六、If-Unmodified-Since

  若是請求的對象在該頭部指定的時間以後沒修改過,才執行請求的動做(好比返回對象)。

  1七、If-Range

  瀏覽器告訴 WEB 服務器,若是我請求的對象沒有改變,就把我缺乏的部分給我,若是對象改變了,就把整個對象給我。瀏覽器經過發送請求對象的ETag 或者本身所知道的最後修改時間給 WEB 服務器,讓其判斷對象是否改變了。老是跟 Range 頭部一塊兒使用。

  1八、Range

  瀏覽器(好比 Flashget 多線程下載時)告訴 WEB 服務器本身想取對象的哪部分。例如:Range: bytes=1173546

  1九、Proxy-Authenticate

  代理服務器響應瀏覽器,要求其提供代理身份驗證信息。

  20、Proxy-Authorization

  瀏覽器響應代理服務器的身份驗證請求,提供本身的身份信息。

  2一、Host

  客戶端指定本身想訪問的WEB服務器的域名/IP 地址和端口號。如Host:rss.sina.com.cn

  2二、Referer

  瀏覽器向WEB 服務器代表本身是從哪一個網頁URL得到點擊當前請求中的網址/URL,例如:Referer:http://www.jb51.net  

        2三、User-Agent

  瀏覽器代表本身的身份(是哪一種瀏覽器)。例如:User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN;rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14

 HTTP響應頭

  響應頭向客戶端提供一些額外信息,好比誰在發送響應、響應者的功能,甚至與響應相關的一些特殊指令。這些頭部有助於客戶端處理響應,並在未來發起更好的請求。響應頭域包含Age、Location、Proxy-Authenticate、Public、Retry- After、Server、Vary、Warning、WWW-Authenticate。對響應頭域的擴展要求通信雙方都支持,若是存在不支持的響應頭域,通常將會做爲實體頭域處理。

  2四、Age

  當代理服務器用本身緩存的實體去響應請求時,用該頭部代表該實體從產生到如今通過多長時間了。

  2五、Server

  WEB 服務器代表本身是什麼軟件及版本等信息。例如:Server:Apache/2.0.61 (Unix)

  2六、Accept-Ranges

  WEB服務器代表本身是否接受獲取其某個實體的一部分(好比文件的一部分)的請求。bytes:表示接受,none:表示不接受。

  2七、Vary

  WEB服務器用該頭部的內容告訴 Cache 服務器,在什麼條件下才能用本響應所返回的對象響應後續的請求。假如源WEB服務器在接到第一個請求消息時,其響應消息的頭部爲:Content-Encoding: gzip; Vary: Content-Encoding,那麼Cache服務器會分析後續請求消息的頭部,檢查其Accept-Encoding,是否跟先前響應的Vary頭部值一致,便是否使用相同的內容編碼方法,這樣就能夠防止Cache服務器用本身Cache 裏面壓縮後的實體響應給不具有解壓能力的瀏覽器。例如:Vary:Accept-Encoding。

 HTTP實體頭

  實體頭部提供了有關實體及其內容的大量信息,從有關對象類型的信息,到可以對資源使用的各類有效的請求方法。總之,實體頭部能夠告知接收者它在對什麼進行處理。請求消息和響應消息均可以包含實體信息,實體信息通常由實體頭域和實體組成。實體頭域包含關於實體的原信息,實體頭包括信息性頭部Allow、Location,內容頭部Content-Base、Content-Encoding、Content-Language、Content-Length、Content-Location、Content-MD五、Content-Range、Content-Type,緩存頭部Etag、Expires、Last-Modified、extension-header。

  2八、Allow

  服務器支持哪些請求方法(如GET、POST等)。

  2九、Location

  表示客戶應當到哪裏去提取文檔,用於將接收端定位到資源的位置(URL)上。Location一般不是直接設置的,而是經過HttpServletResponse的sendRedirect方法,該方法同時設置狀態代碼爲302。

  30、Content-Base

  解析主體中的相對URL時使用的基礎URL。

  3一、Content-Encoding

  WEB服務器代表本身使用了什麼壓縮方法(gzip,deflate)壓縮響應中的對象。例如:Content-Encoding:gzip

  3二、Content-Language

  WEB 服務器告訴瀏覽器理解主體時最適宜使用的天然語言。

  3三、Content-Length

  WEB服務器告訴瀏覽器本身響應的對象的長度或尺寸,例如:Content-Length: 26012

  3四、Content-Location

  資源實際所處的位置。

  3五、Content-MD5

  主體的MD5校驗和。

  3六、Content-Range

  實體頭用於指定整個實體中的一部分的插入位置,他也指示了整個實體的長度。在服務器向客戶返回一個部分響應,它必須描述響應覆蓋的範圍和整個實體長度。通常格式: Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-legth。例如,傳送頭500個字節次字段的形式:Content-Range:bytes0- 499/1234若是一個http消息包含此節(例如,對範圍請求的響應或對一系列範圍的重疊請求),Content-Range表示傳送的範圍,Content-Length表示實際傳送的字節數。

  3七、Content-Type

  WEB 服務器告訴瀏覽器本身響應的對象的類型。例如:Content-Type:application/xml

  3八、Etag

  就是一個對象(好比URL)的標誌值,就一個對象而言,好比一個html文件,若是被修改了,其Etag也會別修改,因此,ETag的做用跟Last-Modified的做用差很少,主要供WEB服務器判斷一個對象是否改變了。好比前一次請求某個html文件時,得到了其 ETag,當此次又請求這個文件時,瀏覽器就會把先前得到ETag值發送給WEB服務器,而後WEB服務器會把這個ETag跟該文件的當前ETag進行對比,而後就知道這個文件有沒有改變了。

  3九、Expires

  WEB服務器代表該實體將在何時過時,對於過時了的對象,只有在跟WEB服務器驗證了其有效性後,才能用來響應客戶請求。是 HTTP/1.0 的頭部。例如:Expires:Sat, 23 May 2009 10:02:12 GMT

  40、Last-Modified

  WEB服務器認爲對象的最後修改時間,好比文件的最後修改時間,動態頁面的最後產生時間等等。例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT

RESTful架構

目前最流行的一種互聯網軟件結構。它結構清晰,符合標準,易於理解,擴展方便。

REST,即Representational State Transfer的縮寫,表現層狀態話轉換。

若是一個架構符合REST原則,則稱爲RESTful架構。

REST的名稱表示層狀態轉化,表示層指資源的表現層

資源,就是網絡上的一個實體,或者網絡上的一個具體信息。能夠是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的實現。能夠用一個URI指向它,每種資源對應一個特定的URI。要獲取這個資源,訪問它的URI就能夠,所以URI就成了每個資源的地址或獨一無二的識別符。

表示層,把資源具體呈現出來的形式,叫作它的表示層。

好比,文本能夠用txt格式表現,也能夠用HTML格式,XML格式,JSON格式表現,甚至能夠採用二進制格式。圖片能夠用JPG格式表現,也能夠用PNG格式表現。

URI只表明資源的屍體,不表明它的形式。

狀態轉化,互聯網通訊協議HTTP協議是一個無狀態協議。全部的狀態都保存在服務器端。所以若是客戶端想要操做服務器,必須經過某種手段,讓服務端發生狀態轉化(State Transfer)。而這種轉化是創建在表現層之上的,就是 表現層狀態轉化。

客戶端用到的手段,只能是HTTP協議。具體來講,HTTP協議裏面,

四個表示操做方式的動詞:GET、POST、PUT、DELETE。分別對應四種基本操做。

  • GET用來獲取資源
  • POST用來新建資源
  • PUT用來更新資源
  • DELETE用來刪除資源

總結如下RESTful架構

  1. 每個URI表示一種資源
  2. 客戶端和服務器之間,傳遞這種資源的某種表現層
  3. 客戶端經過四個HTTP動詞,對服務器資源進行操做,實現表現層狀態轉化

誤區

最多見的一種設計錯誤,就是URI包含動詞。由於資源表示一種實體,因此應該是名詞,URI不該該有動詞,動詞應該放在HTTP協議中。

舉例:某個URI是/post/show/1,其中show是動詞,這個URI就設計錯誤了。正確的是:/post/1,而後用GET方法表示show

若是某些動做是HTTP動詞表達不了的,就應該把動做作成一種資源。

好比網上匯款,錯誤的URI是

POST /accounts/1/transfer/500/to/2

正確的是

POST /transaction HTTP/1.1
  Host: 127.0.0.1
  from=1&to=2&amount=500.00

協議

API與用戶通訊協議,使用HTTPS協議

域名

API部署在專用域名下,使用二級域名:api.example.com

若是很簡單,而且不會進一步擴展,能夠考慮放在主域名下:example.org/api

路徑

RESTful架構中,每個網址表明一種資源,因此網址中不能有動詞,只能有名詞,並且名詞每每與數據庫中的表格名對應。數據庫中的表是同種記錄的集合,因此API中的名詞也應該使用複數

舉例,有一個API提供動物園信息,則路徑應該設計下面這樣

  • https://api.example.com/v1/zoos
  • https://api.example.com/v1/animals
  • https://api.example.com/v1/employees

HTTP動詞

經常使用的HTTP動詞有下面五個

  • GET(SELECT):從服務器取出資源(一項或多項)。
  • POST(CREATE):在服務器新建一個資源。
  • PUT(UPDATE):在服務器更新資源(客戶端提供改變後的完整資源)。
  • PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)。
  • DELETE(DELETE):從服務器刪除資源。

過濾信息

若是記錄數據不少,服務器不可能都將它們返回給用戶。API應該提供參數,過濾返回結果

  • ?limit=10:指定返回記錄的數量
  • ?offset=10:指定返回記錄的開始位置。
  • ?page=2&per_page=100:指定第幾頁,以及每頁的記錄數。
  • ?sortby=name&order=asc:指定返回結果按照哪一個屬性排序,以及排序順序。
  • ?animal_type_id=1:指定篩選條件

狀態嗎

服務器向用戶返回的狀態碼和提示信息,常見的有如下一些

  • 200 OK - [GET]:服務器成功返回用戶請求的數據,該操做是冪等的(Idempotent)。
  • 201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。
  • 202 Accepted - [*]:表示一個請求已經進入後臺排隊(異步任務)
  • 204 NO CONTENT - [DELETE]:用戶刪除數據成功。
  • 400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操做,該操做是冪等的。
  • 401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。
  • 403 Forbidden - [*] 表示用戶獲得受權(與401錯誤相對),可是訪問是被禁止的。
  • 404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操做,該操做是冪等的。
  • 406 Not Acceptable - [GET]:用戶請求的格式不可得(好比用戶請求JSON格式,可是隻有XML格式)。
  • 410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再獲得的。
  • 422 Unprocesable entity - [POST/PUT/PATCH] 當建立一個對象時,發生一個驗證錯誤。
  • 500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將沒法判斷髮出的請求是否成功。

錯誤處理

若是狀態碼是4xx,應該向用戶返回出錯信息。返回的信息將error做爲鍵名,錯誤信息做爲鍵值便可

error: "Invalid API key"

返回結果

針對不一樣操做,服務器向用戶返回的結果應該符合如下規範

  • GET /collection:返回資源對象的列表(數組)
  • GET /collection/resource:返回單個資源對象
  • POST /collection:返回新生成的資源對象
  • PUT /collection/resource:返回完整的資源對象
  • PATCH /collection/resource:返回完整的資源對象
  • DELETE /collection/resource:返回一個空文檔

服務器返回的數據格式,儘可能使用JSON,避免使用XML

OAuth2.0

OAuth是一個關於受權的開放網絡標準。

名詞定義

須要瞭解幾個專用名詞,尤爲是幾張圖

  • Third-party application:第三方應用程序,又稱客戶端
  • HTTP Service:HTTP服務提供商,簡稱服務提供商
  • Resource Owner:資源全部者,又稱用戶
  • User Agent:用戶代理,指瀏覽器
  • Authorization Server:認證服務器,即服務提供商專門用來處理認證的服務器
  • Resource Server:資源服務器,即服務提供商存放用戶生成的資源的服務器。與認證服務器,能夠是同一臺

OAuth的做用就是讓客戶端安全可控地獲取用戶的受權,與服務商提供商進行互動

OAuth的思路

在客戶端與服務提供商之間,設置了一個受權層(authorization layer)。客戶端不能直接登錄服務提供商,只能登錄受權層,以此將用戶客戶端區分開來。客戶端 登錄受權層所用的令牌(token),與用戶的密碼不一樣。用戶能夠在登錄的時候,指定受權層令牌的權限範圍和有效期。

客戶端登錄受權層以後,服務提供商根據令牌的權限範圍和有效期,向客戶端開放用戶存儲的資料

運行流程

B是關鍵,即用戶怎樣才能給與客戶端受權。有了這個受權以後,客戶端就能夠獲取令牌,進而憑藉令牌獲取資源

客戶端受權模式

客戶端必須獲得用戶的受權,才能得到令牌。OAuth定義了四種受權方式

  • 受權碼模式(authorization code)
  • 簡化模式(implicit)
  • 密碼模式(resource owner password credentials)
  • 客戶端模式(client credentials)

受權碼模式 

功能最完整、流程最嚴密的受權模式。特色就是經過客戶端的後臺服務器,與服務提供商的認證服務器進行互動

下面是這些步驟所需的參數

A步驟,客戶端申請認證URI,包含如下參數

  • response_type:表示受權類型,必選項,此處的值固定爲"code"
  • client_id:表示客戶端的ID,必選項
  • redirect_uri:表示重定向URI,可選項
  • scope:表示申請的權限範圍,可選項
  • state:表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值。

例子

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
        &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com

C步驟,服務器迴應客戶端的URI

  • code:表示受權碼,必選項。該碼的有效期應該很短,一般設爲10分鐘,客戶端只能使用該碼一次,不然會被受權服務器拒絕。該碼與客戶端ID和重定向URI,是一一對應關係。
  • state:若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數。

例子

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz

 D步驟,客戶端向認證服務器申請令牌的HTTP請求,包含如下參數

  • grant_type:表示使用的受權模式,必選項,此處的值固定爲"authorization_code"。
  • code:表示上一步得到的受權碼,必選項。
  • redirect_uri:表示重定向URI,必選項,且必須與A步驟中的該參數值保持一致。
  • client_id:表示客戶端ID,必選項。

例子

POST /token HTTP/1.1
Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

E步驟,認證服務器發送HTTP回覆,包含如下參數

  • access_token:表示訪問令牌,必選項。
  • token_type:表示令牌類型,該值大小寫不敏感,必選項,能夠是bearer類型或mac類型。
  • expires_in:表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間。
  • refresh_token:表示更新令牌,用來獲取下一次的訪問令牌,可選項。
  • scope:表示權限範圍,若是與客戶端申請的範圍一致,此項可省略。

例子

HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }

從上面代碼能夠看到,相關參數使用JSON格式發送(Content-Type:application/json)。HTTP頭信息中明確指定不得緩存

簡化模式

不經過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了受權碼這個步驟。

全部步驟在瀏覽器中完成,令牌對訪問者可見,且客戶端不須要認證

下面是上面這些步驟所須要的參數。

A步驟中,客戶端發出的HTTP請求,包含如下參數:

  • response_type:表示受權類型,此處的值固定爲"token",必選項。
  • client_id:表示客戶端的ID,必選項。
  • redirect_uri:表示重定向的URI,可選項。
  • scope:表示權限範圍,可選項。
  • state:表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值。

下面是一個例子。

GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
        &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
    Host: server.example.com

C步驟中,認證服務器迴應客戶端的URI,包含如下參數:

  • access_token:表示訪問令牌,必選項。
  • token_type:表示令牌類型,該值大小寫不敏感,必選項。
  • expires_in:表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間。
  • scope:表示權限範圍,若是與客戶端申請的範圍一致,此項可省略。
  • state:若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數。

下面是一個例子。

HTTP/1.1 302 Found
     Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
               &state=xyz&token_type=example&expires_in=3600

在上面的例子中,認證服務器用HTTP頭信息的Location欄,指定瀏覽器重定向的網址。注意,在這個網址的Hash部分包含了令牌。

根據上面的D步驟,下一步瀏覽器會訪問Location指定的網址,可是Hash部分不會發送。接下來的E步驟,服務提供商的資源服務器發送過來的代碼,會提取出Hash中的令牌。

密碼模式

用戶向客戶端提供本身的用戶名和密碼。客戶端使用這些信息,向"服務商提供商"索要受權。

在這種模式中,用戶必須把本身的密碼給客戶端,可是客戶端不得儲存密碼。這一般用在用戶對客戶端高度信任的狀況下,好比客戶端是操做系統的一部分,或者由一個著名公司出品。而認證服務器只有在其餘受權模式沒法執行的狀況下,才能考慮使用這種模式。

(A)用戶向客戶端提供用戶名和密碼。

(B)客戶端將用戶名和密碼發給認證服務器,向後者請求令牌。

(C)認證服務器確認無誤後,向客戶端提供訪問令牌。

B步驟中,客戶端發出的HTTP請求,包含如下參數:

  • grant_type:表示受權類型,此處的值固定爲"password",必選項。
  • username:表示用戶名,必選項。
  • password:表示用戶的密碼,必選項。
  • scope:表示權限範圍,可選項。

下面是一個例子。

POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded

     grant_type=password&username=johndoe&password=A3ddj3w

C步驟中,認證服務器向客戶端發送訪問令牌,下面是一個例子

HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" } 

整個過程當中,客戶端不得保存用戶的密碼

客戶端模式

客戶端模式(Client Credentials Grant)指客戶端以本身的名義,而不是以用戶的名義,向"服務提供商"進行認證。嚴格地說,客戶端模式並不屬於OAuth框架所要解決的問題。在這種模式中,用戶直接向客戶端註冊,客戶端以本身的名義要求"服務提供商"提供服務,其實不存在受權問題。

A步驟中,客戶端發出的HTTP請求,包含如下參數:

  • granttype:表示受權類型,此處的值固定爲"clientcredentials",必選項。
  • scope:表示權限範圍,可選項。
POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded

     grant_type=client_credentials

認證服務器必須以某種方式,驗證客戶端身份

B步驟中,認證服務器向客戶端發送訪問令牌

HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "example_parameter":"example_value" }

更新令牌

若是用戶訪問的時候,客戶端的"訪問令牌"已通過期,則須要使用"更新令牌"申請一個新的訪問令牌。

客戶端發出更新令牌的HTTP請求,包含如下參數:

  • granttype:表示使用的受權模式,此處的值固定爲"refreshtoken",必選項。
  • refresh_token:表示早前收到的更新令牌,必選項。
  • scope:表示申請的受權範圍,不能夠超出上一次申請的範圍,若是省略該參數,則表示與上一次一致。

例子

POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded

     grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

#

IIS與ASP.NET管道

不一樣IIS版本處理請求也不同

IIS5

IIS 5.x 運行在進程InetInfo.exe中,進程寄宿一個World Wide Web Publishing Service(W3SVC)服務。

W3SVC主要負責HTTP請求的監聽、激活管理工做進程、加載配置等。

當檢測到HTTP請求,IIS根據擴展名判斷請求是靜態仍是動態。

靜態資源,IIS直接響應內容。

動態資源,根據擴展名從IIS的處理程序映射中找到ISAPI動態連接庫(Dynamic Link Library,DLL)

ISAPI,是一套本地的Win32 API,是IIS和其餘動態Web應用或平臺之間的紐帶。

ISAPI支持ISAPI擴展和ISAPI篩選,擴展處理HTTP請求的接口。篩選能夠進行查看,修改,轉發,拒絕。

當收到ASP.NET資源請求,ISAPI會建立ASP.NET工做進程aspnet.exe.

IIS進程與工做進程之間經過命名管道(Named Pipes)進行通訊。

工做進程初始化時,CLR會加載以構建一個託管的環境。對於某個Web應用的初次請求,CLR會爲其建立一個AppDomain應用程序域。

寄存在IIS5.x的全部Web應用都運行在同一個進程的不一樣AppDomain裏面。

IIS6

IIS6針對IIS5有如下兩點修改。

1. 將ISAPI動態連接庫直接加載到工做進程中。

2. IIS6引用應用程序池的機制,能夠爲一個或多個Web應用建立一個應用程序池。以免全部應用都在一個進程裏

能夠爲一個或多個Web應用建立應用程序池,每一個應用程序池對應一個獨立的工做進程,運行在不一樣應用程序池中的Web引用基於進程級別的隔離機制。

IIS6建立了一個HTTP.SYS的監聽器,以驅動程序的形式運行在Windows內核模式下,是TCP/IP網絡子系統的一部分。

HTTP.SYS好處以下

持續監聽:因爲是網絡驅動程序,始終處於運行狀態,對用戶的HTTP請求可以及時做出反應。

更好的穩定性:HTTP.SYS運行在操做系統內核模式下,並不執行任何用戶代碼,自己不會受到Web應用,工做進程,IIS進程的影響。

數據緩存:某個資源被頻繁請求,HTTP.SYS會把響應的內容進行緩存。

W3SVC在IIS6中,從進程InetInfo.exe轉移到SvcHost.exe中了。

當HTTP.SYS監聽到HTTP請求,將其分發給W3SVC進行解析,獲取目標應用,得到目標應用運行的程序池或工做進程。

工做進程初始化過程當中,ISAPI動態庫被加載,負責進行CLR的加載、應用程序域的建立和Web初始化等工做。

IIS7

引入了Windows進程激活服務(Windows Process Activation Service,WAS)分流W3SVC承載的部分功能。

W3SVC有三大功能

1.HTTP請求接受:接受HTTP.SYS監聽到的HTTP請求

2.配置管理:從元數據庫中加載配置信息對相關組件進行配置

3.進程管理:建立、回收、監控工做進程

其中後兩個功能實現到WAS中了。提供了非HTTP協議的支持,經過監聽適配器接口,抽象出針對不一樣協議的監聽器。

對應3中監聽器,他們以Windows服務的形式進行工做。

NetTcpPortSharing:爲WCF提供TCP端口共享,即同一個監聽端口被多個進程共享

NetTcpActivator:爲WAS提供基於TCP的激活請求,包含TCP監聽器和對應的監聽適配器

NetPipeActivator:爲WAS提供命名管道的激活請求

NetMsmqActivator:爲WAS提供基於MSMQ的激活請求

不管是從W3SVC接受到的請求,仍是監聽器接受的請求,最終都會流轉到WAS中。

IIS7分爲兩種模式,經典模式跟IIS6相同,集成模式是一種統一的處理管道。

將ASP.NET請求管道和IIS請求管道組合在一塊兒。能夠提供更好的性能,能夠完成配置和管理的模塊化。繼承模式的映射都在web.config中進行處理。

ASP.NET集成

IIS與ASP.NET是兩個相互獨立的管道,各自具備本身的一套HTTP處理機制。兩個管道經過ISAPI連通。

IIS是第一道屏障,進行必要的前期處理。IIS經過ISAPI將請求分發給ASP.NET管道。

ASP.NET在自身管道範圍內完成對HTTP請求的處理,結束後再返回IIS。IIS在進行後期處理。

IIS運行在非託管的環境中,ASP.NET管道則是託管。託管環境指CLR搭建的環境,非託管環境指能夠由Windows直接調用。

ASP.NET管道

HTTP.SYS接收到HTTP請求是對web應用的第一次訪問,加載CLR後IIS會經過AppDomainFactory建立一個AppDomaiin。

ISApiRuntime被加載,會接管該HTTP請求。

建立一個IsapiWorkerRequest對象封裝當前的HTTP請求,將此對象傳遞給CLR的HttpRuntime(當前應用程序的 ASP.NET 運行時服務)

此時,HTTP請求正式進入ASP.NET管道。HttpRuntime會根據對象建立HTTPContext( HTTP 請求的全部 HTTP 特定的信息)俗稱 請求上下文

HttpContext建立後,HttpRuntime會利用HttpApplicationFacotry建立HttpApplication(ASP.NET 應用程序內全部應用程序對象公用的方法、屬性和事件)

HttpApplication初始化過程當中,ASP.NET會根據配置文件加載並初始化HttpModule(HTTP模塊初始化和處置事件)

HttpApplication會在處理HTTP請求的不一樣階段觸發不一樣的事件,HttpModule經過註冊事件, 將操做注入HTTP請求處理流程中。

HttpApplication

(定義對 ASP.NET 應用程序內全部應用程序對象公用的方法、屬性和事件。 此類是用戶在 Global.asax 文件中定義的應用程序的基類)

整個ASP.NET基礎架構的核心,負責處理分發給它的HTTP請求。

第一個請求抵達後,會建立多個HttpApplication對象,存放於對象池中。

在HTTPAppliccation處理請求的不一樣階段會觸發不一樣的事件。

對於ASP.NET應用來講,HttpApplication派生於Global.asax文件,能夠經過此文件,對請求處理行爲進行制定。

Global.asax 採用方法名匹配,按照「Application_{事件名}」進行事件註冊。

其中事件名內容,就是Application中包含的事件。例如:

protected void Application_BeginRequest(Object sender, EventArgs e) 
{ 
   Application["StartTime"] = System.DateTime.Now; 
} 

其中會有幾個是針對整個應用程序而言,而不是針對請求。

  1. Application_Init:在每個HttpApplication實例初始化的時候執行 
  2. Application_Disposed:在每個HttpApplication實例被銷燬以前執行
  3. Application_Error:全部沒有處理的錯誤都會致使這個方法的執行
  4. Application_Start:在程序初始化的時候執行。在Web應用程序的生命週期裏就執行一次,這裏只能放一些公用的信息,好比HttpApplicationState
  5. Application_End:應用程序結束時,在最後一個HttpApplication銷燬以後執行。對應Application_Start,在整個生命週期裏面也是隻執行一次
  6. Session_Start:會話開始時執行
  7. Session_End:會話結束或過時時執行

請求事件執行順序以下:

  1. BeginRequest:做爲執行的 HTTP 管道鏈中的第一個事件發生,當 ASP.NET 的請求作出響應
  2. AuthenticateRequest:當安全模塊已創建的用戶標識時出現
  3. PostAuthenticateRequest:當安全模塊已創建的用戶標識時出現
  4. AuthorizeRequest:安全模塊已驗證用戶身份驗證時發生
  5. PostAuthorizeRequest:當前請求的用戶已被受權時發生
  6. ResolveRequestCache:當 ASP.NET 完成受權事件以便從緩存中,跳過的事件處理程序 (例如,一個頁面或 XML Web 服務) 執行的請求提供服務的緩存模塊時發生。
  7. PostResolveRequestCache:ASP.NET 將繞過當前事件處理程序的執行,並容許緩存模塊以處理從緩存請求時發生
  8. PostMapRequestHandler:當 ASP.NET 已映射到相應的事件處理程序的當前請求時出現
  9. AcquireRequestState:當 ASP.NET 獲取與當前的請求相關聯的當前狀態 (例如,會話狀態)
  10. PostAcquireRequestState:獲取與當前的請求相關聯的請求狀態 (例如,會話狀態) 時發生
  11. PreRequestHandlerExecute:ASP.NET 開始執行事件處理程序 (例如,一個頁面或 XML Web 服務) 以前發生
  12. PostRequestHandlerExecute:當 ASP.NET 事件處理程序 (例如,一個頁面或 XML Web 服務) 完成執行時發生
  13. ReleaseRequestStateASP.NET 完成執行全部請求事件處理程序後發生。 此事件會致使狀態模塊保存當前的狀態數據
  14. PostReleaseRequestState:當 ASP.NET 已完成執行全部請求事件處理程序和存儲數據的請求狀態時發生
  15. UpdateRequestCache:當 ASP.NET 完成執行事件處理程序,以便讓緩存模塊存儲將用於爲從緩存中的後續請求提供服務的響應時發生
  16. PostUpdateRequestCache:當 ASP.NET 完成更新的緩存模塊和存儲用於爲從緩存中的後續請求提供服務的響應時發生
  17. LogRequest:ASP.NET 執行當前請求的任何日誌記錄以前發生
  18. PostLogRequest:當 ASP.NET 已完成處理的事件處理程序時發生 LogRequest 事件
  19. EndRequest:做爲執行的 HTTP 管道鏈中的最後一個事件發生,當 ASP.NET 的請求作出響應

IHttpModule

(提供模塊初始化和處置事件以實現類)

當請求轉入ASP.NET管道時,最終負責處理該請求的是HttpHandler對象。在此以前會先加載HttpModule對象。

ASP.NET提供的不少基礎功能都是經過HttpModule實現的。例如

OutputCacheModule:輸出緩存功能

SessionStateModule:無狀態的HTTP協議上實現基於會話的狀態保持

WindowsAuthenticationModule + FormsAuthenticationModule + PassportAuthenticatinonModule:實現了三種典型的身份認證

UrlAuthorizationModule _ FileAuthorizationModule:基於URI和ACL文件的受權

IHttpHandler

(定義 ASP.NET 以異步方式處理使用自定義 HTTP 處理程序的 HTTP Web 請求而實現的協定)

對不一樣資源類型的請求,ASP.NET會加載不一樣的Handler來處理,好比aspx與asmx對應的Handler是不一樣的。

HttpHandler 能夠配置到Web.config中。例子爲svc資源的配置。

<system.web>
    <httpHandlers>
      <add path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHander" validate="false" />
    </httpHandlers>
    <compilation debug="true" targetFramework="4.6" />
    <httpRuntime targetFramework="4.6" />
    <authentication mode="Forms">
      <forms loginUrl="~/Account/login.aspx" timeout="2000"></forms>
    </authentication>
  </system.web>
相關文章
相關標籤/搜索