http報文解析, 網(wǎng)絡通信協(xié)議類型,cookie,token, 冪等性

header:
    header里面的信息, 是給瀏覽器看的, 包括以何種編碼方式解析body等

body:
    body里面的信息, 是給用戶看的

HTTP報文:

它是HTTP應用程序之間發(fā)送的數(shù)據(jù)塊。
這些數(shù)據(jù)塊以一些文本形式的元信息開頭淀散,這些信息描述了報文的內(nèi)容及含義右莱,后面跟著可選的數(shù)據(jù)部分。
這些報文都是在客戶端档插、服務器和代理之間流動慢蜓。

HTTP報文的流動方向:

一次HTTP請求,HTTP報文會從“客戶端”流到“代理”再流到“服務器”阀捅,
在服務器工作完成之后胀瞪,報文又會從“服務器”流到“代理”再流到“客戶端”

報文的語法:

所有的HTTP報文都可以分為兩類,請求報文和響應報文。
請求和響應報文的基本報文結構大致是相同的凄诞,只有起始行的語法有所不同圆雁。

1.1請求報文:

它會向Web服務器請求一個動作

請求報文的格式:

起始行: <method> <request-URL> <version>
頭部:   <headers>
主體:   <entity-body>

1.2響應報文:

它會將請求的結果返回給客戶端。

響應報文的格式:

起始行:  <version> <status> <reason-phrase>
頭部:    <headers>
主體:    <entity-body>

下面是對各部分的簡要描述

1帆谍、請求方法(method):
客戶端希望服務器對資源執(zhí)行的動作
比如伪朽,GET, POST, HEAD, DELETE, OPTIONS, PUT, TRACE

2、請求URL(request-URL):
要直接與服務器進行對話汛蝙,只要請求URL是資源的絕對路徑就可以了烈涮,服務器可以假定自己是URL的主機/端口

3、版本(version):
報文所使用的HTTP版本窖剑。
格式:HTTP/<主要版本號>.<次要版本號>

4坚洽、狀態(tài)碼(status-code):
狀態(tài)碼是三位數(shù)字,描述了請求過程中所發(fā)生的情況西土。
每個狀態(tài)碼的第一位數(shù)字都用于描述狀態(tài)的一般類別(比如讶舰,“成功”、“出錯”等等)

5需了、原因短語(reason-phrase):
數(shù)字狀態(tài)碼的可讀版本跳昼,包含行終止序列之前的所有文本。
原因短語只對人類有意義肋乍,
因此鹅颊,盡管響應行HTTP/1.0 200 NOT OK和HTTP/1.0 200 OK中原因短語的含義不同,
但同樣都會被當作成功指示處理

6墓造、頭部(header):
可以有零個或多個頭部堪伍,
每個首部都包含一個名字,后面跟著一個冒號(:)觅闽,
然后是一個可選的空格杠娱,接著是一個值,
最后是一個CRLF首部是由一個空行(CRLF, Carriage-Return Line-Feed, 回車換行)結束的谱煤,
表示了頭部列表的結束和實體主體部分的開始

7、實體的主體部分(entity-body):
實體的主體部分包含一個由任意數(shù)據(jù)組成的數(shù)據(jù)塊禽拔,
并不是所有的報文都包含實體的主體部分刘离,有時,報文只是以一個CRLF結束睹栖。

2.報文詳解

舉例如下

圖片.png

HTTP報文的組成部分:

對報文進行描述的
1.起始行
2.包含屬性的頭部塊
3.可選的硫惕,包含數(shù)據(jù)的主體部分

2.1起始行

所有的HTTP報文都以一個起始行作為開始。

請求報文的起始行說明了要做些什么野来。
響應報文的起始行說明發(fā)生了什么恼除。

請求報文的起始行:
該行包含了一個方法和一個請求的URL,還包含HTTP 的版本。
響應報文的起始行:
該行包含了響應報文使用的HTTP版本豁辉、數(shù)字狀態(tài)碼令野、原因短語。

2.2頭部

HTTP首部字段向請求和響應報文中添加了一些附加信息徽级。
本質(zhì)上來說气破,它們只是一些key/value的列表。
頭部和協(xié)議配合工作餐抢,共同決定了客戶端和服務器能做什么事情现使。

頭部的分類

2.2.1通用頭部

既可以出現(xiàn)在請求報文中,也可以出現(xiàn)在響應報文中旷痕,它提供了與報文相關的最基本的信息
Connection:允許客戶端和服務器指定與請求/響應連接有關的選項

Date:提供日期和時間標志碳锈,說明報文是什么時間創(chuàng)建的

MIME-Version:給出了發(fā)送端使用的MIME版本

Trailer:如果報文采用了分塊傳輸編碼方式,就可以用這個首部列出位于報文拖掛部分的首部集合

Transfer-Encoding:告知接收端為了保證報文的可靠傳輸欺抗,對報文采用了什么編碼方式

Update:給出了發(fā)送端可能想要“升級”使用的新版本或協(xié)議

Via:顯示了報文經(jīng)過的中間節(jié)點(代理售碳、網(wǎng)關)

Cache-Control:用于隨報文傳送緩存指示

2.2.2請求頭部

請求頭部是只在請求報文中有意義的頭部。
用于說明是誰或什么在發(fā)送請求佩迟、請求源自何處团滥,或者客戶端的喜好及能力
Client-IP:提供了運行客戶端的機器的IP地址

From:提供了客戶端用戶的E-mail地址

Host:給出了接收請求的服務器的主機名和端口號

Referer:提供了包含當前請求URI的文檔的URL
#表明產(chǎn)生請求的網(wǎng)頁來自于哪個URL,用戶是從該 Referer頁面訪問到當前請求的頁面报强。這個屬性可以用來跟蹤Web請求來自哪個頁面灸姊,是從什么網(wǎng)站來的等。
#有時候遇到下載某網(wǎng)站圖片秉溉,需要對應的referer力惯,否則無法下載圖片,那是因為人家做了防盜鏈召嘶,原理就是根據(jù)referer去判斷是否是本網(wǎng)站的地址父晶,如果不是,則拒絕弄跌,如果是甲喝,就可以下載;

UA-Color:提供了與客戶端顯示器的顯示顏色有關的信息

UA-CPU:給出了客戶端CPU的類型或制造商

UA-OS:給出了運行在客戶端機器上的操作系統(tǒng)名稱及版本

UA-Pixels:提供了客戶端顯示器的像素信息

User-Agent:將發(fā)起請求的應用程序名稱告知服務器       

Accept:告訴服務器能夠發(fā)送哪些媒體類型

Accept-Charset:告訴服務器能夠發(fā)送哪些字符集

Accept-Encoding:告訴服務器能夠發(fā)送哪些編碼方式

Accept-Language:告訴服務器能夠發(fā)送哪些語言

TE:告訴服務器可以使用那些擴展傳輸編碼

Expect:允許客戶端列出某請求所要求的服務器行為

Range:如果服務器支持范圍請求铛只,就請求資源的指定范圍

If-Match:如果實體標記與文檔當前的實體標記相匹配埠胖,就獲取這份文檔

If-Modified-Sinec:除非在某個指定的日期之后資源被修改過,否則就限制這個請求

If-None-Match:如果提供的實體標記與當前文檔的實體標記不相符淳玩,就獲取文檔

If-Range:允許對文檔的某個范圍進行條件請求

If-Unmodified-Since:除非在某個指定日期之后資源沒有被修改過直撤,否則就限制這個請求

Authorization:包含了客戶端提供給服務器,以便對其自身進行認證的數(shù)據(jù)

Cookie:客戶端用它向服務器傳送數(shù)據(jù)

Cookie2:用來說明請求端支持的cookie版本

Max-Forward:在通往源端服務器的路徑上蜕着,將請求轉(zhuǎn)發(fā)給其他代理或網(wǎng)關的最大次數(shù)

Proxy-Authorization:這個首部在與代理進行認證時使用的

Proxy-Connection:這個首部是在與代理建立連接時使用的

Upgrade-Insecure-Requests (升級為HTTPS請求):
#升級不安全的請求谋竖,意思是會在加載 http 資源時自動替換成 https 請求,讓瀏覽器不再顯示https頁面中的http請求警報。
#HTTPS 是以安全為目標的 HTTP 通道蓖乘,所以在 HTTPS 承載的頁面上不允許出現(xiàn) HTTP 請求锤悄,一旦出現(xiàn)就是提示或報錯。

x-requested-with : XMLHttpRequest  (是Ajax 異步請求)

2.2.3響應頭部

響應頭部為客戶端提供了一些額外信息驱敲,
比如誰在發(fā)送響應铁蹈、響應者的功能,甚至與響應相關的一些特殊指令
Age:(從最初創(chuàng)建開始)響應持續(xù)時間

Public:服務器為其資源支持的請求方法列表

Retry-After:如果資源不可用的話众眨,在此日期或時間重試

Server:服務器應用程序軟件的名稱和版本

Title:對HTML文檔來說握牧,就是HTML文檔的源端給出的標題

Warning:比原因短語更詳細一些的警告報文

Accept-Ranges:對此資源來說,服務器可接受的范圍類型

Vary:服務器會根據(jù)這些首部的內(nèi)容挑選出最適合的資源版本發(fā)送給客戶端

Proxy-Authenticate:來自代理的對客戶端的質(zhì)詢列表

Set-Cookie:在客戶端設置數(shù)據(jù)娩梨,以便服務器對客戶端進行標識

Set-Cookie2:與Set-Cookie類似

WWW-Authenticate:來自服務器的對客戶端的質(zhì)詢列表

2.2.4實體首部

描述主體的長度和內(nèi)容沿腰,或者資源自身
Allow:列出了可以對此實體執(zhí)行的請求方法

Location:告知客戶端實體實際上位于何處,用于將接收端定向到資源的位置(URL)上去

Content-Base:解析主體中的相對URL時使用的基礎URL

Content-Encoding:對主體執(zhí)行的任意編碼方式

Content-Language:理解主體時最適宜使用的自然語言

Content-Length:主體的長度

Content-Location:資源實際所處的位置

Content-MD5:主體的MD5校驗和

Content-Range:在整個資源中此實體表示的字節(jié)范圍

Content-Type:這個主體的對象類型

ETag:與此實體相關的實體標記

Expires:實體不再有效狈定,要從原始的源端再次獲取實體的日期和時間

Last-Modified:這個實體最后一次被修改的日期和時間

2.2.5擴展首部

規(guī)范中沒有定義的新首部颂龙,開發(fā)者可以自定義一個首部的key/value

2.3實體的主體部分

該部分其實就是HTTP要傳輸?shù)膬?nèi)容,是可選的纽什。
HTTP報文可以承載很多類型的數(shù)字數(shù)據(jù)措嵌,
比如,圖片芦缰、視頻企巢、HTML文檔電子郵件、軟件應用程序等等让蕾。

2.4HTTP方法

并不是每個服務器都實現(xiàn)了所有的方法浪规。
即使服務器實現(xiàn)了所有這些方法,這些方法的使用很可能也是受限的探孝。
例如笋婿,支持DELETE方法或PUT方法的服務器可能并不希望任何人都能夠刪除或存儲資源,
這些限制通常都是在服務器的配置中進行設置的顿颅。

常用的HTTP方法

GET方法(不包含主體):
通常用于請求服務器發(fā)送某個資源缸濒。

HEAD方法(不包含主體):
與GET方法類似,但服務器在響應中只返回首部粱腻,
使用HEAD方法可以在不獲取資源的情況下了解資源的情況(比如绍填,判斷其類型)溜族;
通過查看響應中的狀態(tài)碼,看看某個對象是否存在丸冕;
通過查看首部粟瞬,測試資源是否被修改了;

POST方法(包含主體):
該方法是用來向服務器發(fā)送數(shù)據(jù)的潦匈,常用于HTML表單

PUT方法(包含主體):
該方法的語義就是讓服務器用請求的主體部分來創(chuàng)建一個由所請求的URL命名的新文檔捺宗,
如果那個URL已經(jīng)存在的話竞端,就用這個主體來替代它萝快。

TRACE方法(不包含主體):
主要用于驗證請求是否如愿穿過了請求/響應鏈

OPTIONS方法(不包含主體):
決定可以在服務器上執(zhí)行那些方法

DELETE方法(不包含主體):
該方法就是請服務器刪除請求URL所指定的資源锻霎,
但是客戶端應用程序無法保證刪除操作一定會被執(zhí)行,
因為HTTP規(guī)范允許服務器在不通知客戶端的情況下撤銷請求

擴展方法:
指的是沒有在HTTP/1.1規(guī)范中定義的方法揪漩,
這些方法為開發(fā)者提供了一種擴展這些HTTP服務能力的手段旋恼。

2.5狀態(tài)碼

HTTP狀態(tài)碼被分成了五大類。狀態(tài)碼為客戶端提供了一種理解事務處理結果的便捷方式奄容。
1冰更、100~199(信息性狀態(tài)碼):
HTTP/1.1向協(xié)議中引入了信息性狀態(tài)碼

2、200~299(成功狀態(tài)碼):
客戶端發(fā)起請求時昂勒,這些請求通常都是成功的蜀细。
服務器有一組用來表示成功的狀態(tài)碼,分別對應于不同類型的請求

3戈盈、300~399(重定向狀態(tài)碼):
重定向狀態(tài)碼要么告知客戶端使用替代位置來訪問他們所感興趣的資源奠衔,
要么就提供一個替代的響應而不是資源的內(nèi)容

4、400~499(客戶端錯誤狀態(tài)碼):
有時客戶端會發(fā)送一些服務器無法處理的東西塘娶。
瀏覽網(wǎng)頁時归斤,我們都看到過臭名昭著的404 Not Found錯誤碼,
這只是服務器在告訴我們刁岸,它對我們請求的資源一無所知

5脏里、500~599(服務器錯誤狀態(tài)碼):
有時客戶端發(fā)送了一條有效請求,服務器自身卻出錯了难捌,這些會返回5xx狀態(tài)碼

3.網(wǎng)絡通信

3.1常見的網(wǎng)絡通信協(xié)議

http協(xié)議

超文本傳輸協(xié)議方案膝宁,除了沒有用戶名和密碼之外,
與通用的URL格式相符根吁,如果省略了端口员淫,就默認為80

基本格式:http://<host>:<port>/<path>?<query>#<frag>

示例:http://www.baidu.com:80/index.html

https協(xié)議

該方案與http方案是一對的,唯一的區(qū)別在于方案https使用了網(wǎng)景的SSL击敌,
SSL為HTTP連接提供了端到端的加密機制介返,其語法與HTTP的語法相同,默認端口為443

基本格式:https://<host>:<port>/<path>?<query>#<frag>

示例:https://www.baidu.com:80/index.html

mailto協(xié)議

mailto URL指向的是E-mail地址沃斤,由于E-mail的行為與其他方案都有所不同圣蝎,
它并不指向任何可以直接訪問的對象

基本格式:mailto:<RFC-822-addr-spec>

示例:mailto:joe@joes-hardware.com

ftp協(xié)議

文件傳輸協(xié)議URL可以用來從FTP服務器上下載或向其上載文件,
并獲取FTP服務器上的目錄結構內(nèi)容的列表

基本格式:ftp:<user>:<password>@<host>:<port>/<path>;<params>

示例:ftp://anonymous:joe%40joes@prep.an.edu:21/pub/gs

rtsp和rtspu協(xié)議

RTSP URL是可以通過實時流傳輸協(xié)議解析的音/視頻媒體資源的標示符衡瓶。
方案respu中的u表示它是使用UDP協(xié)議來獲取資源的

基本格式:rtsp:<user>:<password>@<host>:<port>/<path>

示例:rtspu://www.baidu.com:554/inte/cto_video

file協(xié)議

file方案表示一臺指定主機上可直接訪問的文件徘公。
各字段都遵循通用格式,如果省略了主機名哮针,就默認為正在使用URL的本地主機

基本格式:file:<user>:<password>@<host>:<port>/<path>

示例:file://OFFICE-FS/poli/cds.doc

telnet協(xié)議

telnet方案用于訪問交互式業(yè)務关面,它表示的并不是對象自身坦袍,
而是可通過telnet協(xié)議訪問的交互式應用程式(資源)。

基本格式:telnet://<user>:<password>@<host>:<port>/

示例:telnet:csh:webcsh@joes.com:50/

3.2 ip分類 & port詳解

每一個IP地址包括兩部分:網(wǎng)絡地址和主機地址
ip地址.jpg

3.2.1 A類IP地址

一個A類IP地址由1字節(jié)的網(wǎng)絡地址和3字節(jié)主機地址組成等太,網(wǎng)絡地址的最高位必須是“0”捂齐,

地址范圍1.0.0.1-126.255.255.254

二進制表示為:00000001 00000000 00000000 00000001 - 01111110 11111111 11111111 11111110

可用的A類網(wǎng)絡有126個,每個網(wǎng)絡能容納1677214個主機

3.2.2 B類IP地址

一個B類IP地址由2個字節(jié)的網(wǎng)絡地址和2個字節(jié)的主機地址組成缩抡,網(wǎng)絡地址的最高位必須是“10”奠宜,

地址范圍128.1.0.1-191.255.255.254

二進制表示為:10000000 00000001 00000000 00000001 - 10111111 11111111 11111111 11111110

可用的B類網(wǎng)絡有16384個,每個網(wǎng)絡能容納65534主機

3.2.3 C類IP地址

一個C類IP地址由3字節(jié)的網(wǎng)絡地址和1字節(jié)的主機地址組成瞻想,網(wǎng)絡地址的最高位必須是“110”

范圍192.0.1.1-223.255.255.254

二進制表示為: 11000000 00000000 00000001 00000001 - 11011111 11111111 11111110 11111110

C類網(wǎng)絡可達2097152個压真,每個網(wǎng)絡能容納254個主機

3.2.4 D類地址用于多點廣播

D類IP地址第一個字節(jié)以“1110”開始,它是一個專門保留的地址内边。

它并不指向特定的網(wǎng)絡榴都,目前這一類地址被用在多點廣播(Multicast)中

多點廣播地址用來一次尋址一組計算機 s 地址范圍224.0.0.1-239.255.255.254

3.2.5 E類IP地址

以“1111”開始,為將來使用保留

E類地址保留漠其,僅作實驗和開發(fā)用

3.2.6 私有ip

在這么多網(wǎng)絡IP中嘴高,國際規(guī)定有一部分IP地址是用于我們的局域網(wǎng)使用,也就

是屬于私網(wǎng)IP和屎,不在公網(wǎng)中使用的拴驮,它們的范圍是:

10.0.0.0~10.255.255.255

172.16.0.0~172.31.255.255

192.168.0.0~192.168.255.255

3.2.7 注意

IP地址127.0.0.1~127.255.255.255用于回路測試,

如:127.0.0.1可以代表本機IP地址柴信,用http://127.0.0.1就可以測試本機中配置的Web服務器套啤。

3.2.8 port分類

第一類公認端口(Well Known Ports):
從0到1023,它們緊密綁定(binding)于一些服務随常。
通常這些端口的通訊明確表明了某種服務的協(xié)議潜沦,必須要有Root權限才能綁定。
例如:80端口實際上總是HTTP通訊绪氛。

第二類注冊端口(Registered Ports):
從1024到49151唆鸡。它們松散地綁定于一些服務。
也就是說有許多服務綁定于這些端口枣察,這些端口同樣用于許多其它目的争占。
例如:許多系統(tǒng)處理動態(tài)端口從1024左右開始。

第三類動態(tài)和/或私有端口(Dynamic, private or ephemeral ports):從49152到65535序目。
理論上臂痕,不應為服務分配這些端口。
實際上猿涨,機器通常從1024起分配動態(tài)端口握童。
但也有例外:SUN的RPC端口從32768開始。

4.cookie, session, token

http協(xié)議(包括http2.0)都是無狀態(tài)協(xié)議.

無狀態(tài)是指協(xié)議對于事務處理沒有記憶功能叛赚。
缺少狀態(tài)意味著澡绩,假如后面的處理需要前面的信息片效,
則前面的信息必須重傳,這樣可能導致每次連接傳送的數(shù)據(jù)量增大英古。
另一方面,在服務器不需要前面信息時昙读,應答就較快召调。
直觀地說,就是每個請求都是獨立的蛮浑,與前面的請求和后面的請求都是沒有直接聯(lián)系的唠叛。

實際中的使用情況

在web應用中,我們使用http協(xié)議沮稚,但是我們需要的web是有狀態(tài)的艺沼,
因此加入了cookie、session等機制用于跟蹤用戶的狀態(tài), 從而實現(xiàn)有狀態(tài)的web蕴掏。

4.1cookie

cookie障般,有時也用其復數(shù)形式cookies,
指某些網(wǎng)站為了辨別用戶身份, 進行session跟蹤而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)盛杰。

cookie是由服務器端生成挽荡,發(fā)送給瀏覽器,
瀏覽器把cookie以kv形式保存到某個目錄下的文本文件內(nèi)即供,
下一次請求同一網(wǎng)站時會把該cookie發(fā)送給服務器定拟。
由于cookie是存在客戶端上的,所以瀏覽器加入了一些限制確保cookie不會被惡意使用逗嫡,
同時不會占據(jù)太多磁盤空間青自,所以每個域的cookie數(shù)量是有限的。
1.  cookie是一門客戶端緩存技術
2.  cookie數(shù)據(jù)由服務器生成驱证,發(fā)送給瀏覽器保存
3.  cookie數(shù)據(jù)的格式:鍵值對
4.  cookie數(shù)據(jù)過期機制:設置expire值

4.2session

1.session是一門服務端會話緩存技術延窜。
2.session由服務器端的web容器創(chuàng)建,保存在服務器端雷滚。
3.session保存數(shù)據(jù):鍵值對形式
4.session過期:默認30分鐘
session 從字面上講需曾,就是會話。
這個就類似于你和一個人交談祈远,你怎么知道當前和你交談的是張三而不是李四呢呆万?
對方肯定有某種特征(長相等)表明他就是張三。

session 也是類似的道理车份,服務器要知道當前發(fā)請求給自己的是誰谋减。
為了做這種區(qū)分,服務器就要給每個客戶端分配不同的“身份標識”扫沼,
然后客戶端每次向服務器發(fā)請求的時候出爹,都帶上這個“身份標識”庄吼,
服務器就知道這個請求來自于誰了。
至于客戶端怎么保存這個“身份標識”严就,可以有很多種方式总寻,
對于瀏覽器客戶端,大家都默認采用 cookie 的方式梢为。

服務器使用session把用戶的信息臨時保存在了服務器上渐行,用戶離開網(wǎng)站后session會被銷毀。
這種用戶信息存儲方式相對cookie來說更安全铸董,可是session有一個缺陷:
如果web服務器做了負載均衡祟印,那么下一個操作請求到了另一臺服務器的時候session會丟失。
也就是要解決session共享的問題:
可以另外設計一套專門的session的服務service, 專門用于存儲登錄認證信息, 如redis集群...

但是會有新的問題:
a.每次認證用戶發(fā)起請求時粟害,服務器需要去創(chuàng)建一個記錄來存儲信息蕴忆。
當越來越多的用戶發(fā)請求時,內(nèi)存的開銷也會不斷增加悲幅。
b.可擴展性:在服務端的內(nèi)存中使用Seesion存儲登錄信息套鹅,伴隨而來的是可擴展性問題。

4.3token(防CSRF攻擊)

基于Token的驗證原理

基于Token的身份驗證是無狀態(tài)的夺艰,我們不將用戶信息存在服務器或Session中芋哭。
這種概念解決了在服務端存儲信息時的許多問題
NoSession意味著你的程序可以根據(jù)需要去增減機器,而不用去擔心用戶是否登錄郁副。

基于Token的身份驗證的過程如下

生成的token减牺,客戶端可將token寫入sessionStorage,服務端可將token加密寫入redis集群

1.用戶通過用戶名和密碼發(fā)送請求存谎。

2.程序驗證拔疚。

3.程序返回一個簽名的token 給客戶端。
<!--
為防止有人偽造token, 可以對數(shù)據(jù)做一個簽名既荚,
比如用<HMAC-SHA256>算法稚失,加上一個<密鑰>, 對數(shù)據(jù)做一個簽名, 
把這個簽名和數(shù)據(jù)一起作為token, 由于密鑰別人不知道, 就無法偽造token了恰聘。
-->
<!--
服務端不保存token, 當客戶端把這個token發(fā)過來時, 再用同樣的<HMAC-SHA256>算法和同樣的<密鑰>, 
對數(shù)據(jù)再計算一次簽名, 和token中的簽名做個比較, 
如果相同, 我就知道小F已經(jīng)登錄過了, 
如果不相同, 數(shù)據(jù)部分肯定被人篡改過, 我就告訴發(fā)送者: 對不起句各,沒有認證。
-->
<!--
token中的數(shù)據(jù)是明文保存的(雖然可以用Base64做下編碼, 但那不是加密), 
還是可以被別人看到的晴叨, 所以不能在其中保存像密碼這樣的敏感信息凿宾。

當然token也可以加密保存!!!
-->

4.客戶端儲存token,并且每次用于每次發(fā)送請求時, 在header中攜帶改token字段。

5.服務器端采用filter過濾器校驗兼蕊。
校驗成功則返回請求數(shù)據(jù)初厚,校驗失敗則返回錯誤碼驗證token并返回數(shù)據(jù)。

每一次請求都需要token孙技。
token應該在HTTP的頭部發(fā)送從而保證了Http請求無狀態(tài)产禾。
我們同樣通過設置服務器屬性Access-Control-Allow-Origin:* 排作,讓服務器能接受到來自所有域的請求。
需要注意的是亚情,在ACAO頭部標明(designating)*時妄痪,不得帶有向HTTP認證,客戶端SSL證書和cookies的證書楞件。
token-1.png

token-2.png

實現(xiàn)思路

圖片.png

app項目為例

一般app項目都會基于一個token做鑒權拌夏。
因為此時客戶端不是瀏覽器,因此就沒有cookie這一說了履因。
當用戶登錄app時,服務器會響應回來一個token信息
(一般都是返回的一串唯一的標識符盹愚,比如說uuid或其他)栅迄。
服務器端會將登錄用戶跟token(票據(jù))保存一個映射關系,
一般保存在redis或者表里面皆怕,服務器端響應回來的token會緩存在手機的本地緩存里毅舆,
后面手機去訪問app的其他頁面,就會帶著這個token去服務器做驗證愈腾,
如果通過這個token能夠從redis找到登錄用戶信息, 那么就認為你是已經(jīng)登錄了的用戶憋活。

Tokens的優(yōu)勢

1.無狀態(tài)、可擴展
在客戶端存儲的Tokens是無狀態(tài)的虱黄,并且能夠被擴展悦即。
基于這種無狀態(tài)和不存儲Session信息,負載負載均衡器能夠?qū)⒂脩粜畔囊粋€服務傳到其他服務器上橱乱。
如果我們將已驗證的用戶的信息保存在Session中辜梳,則每次請求都需要用戶向已驗證的服務器發(fā)送驗證信息(稱為Session親和性)。
用戶量大時泳叠,可能會造成一些擁堵作瞄。但是不要著急。
使用tokens之后這些問題都迎刃而解危纫,因為tokens自己hold住了用戶的驗證信息宗挥。

2.安全性(可先驗證referer,再驗證token)
請求中發(fā)送token而不再是發(fā)送cookie能夠防止CSRF(跨站請求偽造)种蝶。
即使在客戶端使用cookie存儲token契耿,cookie也僅僅是一個存儲機制而不是用于認證。
不將信息存儲在Session中蛤吓,讓我們少了對session操作宵喂。 
token是有時效的,一段時間之后用戶需要重新驗證会傲。
我們也不一定需要等到token自動失效锅棕,token有撤回的操作拙泽,
通過token revocataion可以使一個特定的token或是一組有相同認證的token無效。

4.可擴展性
tokens能夠創(chuàng)建與其它程序共享權限的程序裸燎。
例如顾瞻,能將一個隨便的社交帳號和自己的大號(Fackbook或是Twitter)聯(lián)系起來。
當通過服務登錄Twitter(我們將這個過程Buffer)時德绿,我們可以將這些Buffer附到Twitter的數(shù)據(jù)流上荷荤。
使用tokens時,可以提供可選的權限給第三方應用程序移稳。
當用戶想讓另一個應用程序訪問它們的數(shù)據(jù)蕴纳,我們可以通過建立自己的API,得出特殊權限的tokens个粱。

5.多平臺跨域
我們提前先來談論一下CORS(跨域資源共享)古毛,對應用程序和服務進行擴展的時候,需要介入各種各種的設備和應用程序都许。
<Access-Control-Allow-Origin: *>

4.4cookie與session有什么區(qū)別

1)session是服務器端保存用戶信息稻薇,cookie是在客戶端保存用戶信息。
2)session中保存的是對象胶征,cookie保存的是字符串塞椎。
3)session對象隨會話結束而關閉,cookie可以長期保存在客戶端
4)cookie通常用于保存不重要的用戶信息睛低,重要的信息使用session保存案狠。

一些反對意見

http://www.reibang.com/p/af8360b83a9f

5.接口冪等性

什么是冪等性

Methods can also have the property of “idempotence” in that 
(aside from error or expiration issues) 
the side-effects of N > 0 identical requests is the same as for a single request.

#在分布式集群環(huán)境中提供對外冪等性的接口:
只要調(diào)用接口成功,外部對接口的多次調(diào)用得到的結果是相同的钱雷。
即執(zhí)行多次和一次的效果是一樣的莺戒。
冪等性, 通俗的說就是一個接口, 多次發(fā)起同一個請求, 必須保證操作只能執(zhí)行一次,比如:
>>訂單接口, 不能多次創(chuàng)建訂單
>>支付接口, 重復支付同一筆訂單只能扣一次錢
>>支付寶回調(diào)接口, 可能會多次回調(diào), 必須處理重復回調(diào)
>>普通表單提交接口, 因為網(wǎng)絡超時等原因多次點擊提交, 只能成功一次

什么情況下需要保證冪等性


GET、HEAD急波、OPTIONS和TRACE方法被定義成安全的从铲,它們只是為了獲取數(shù)據(jù),
多個相同請求時服務器端的表現(xiàn)是相同的澄暮,所以它們是天然冪等的名段。

PUT和DELETE方法被定義為冪等的。需要注意了泣懊。

以SQL為例伸辟,有下面三種場景,只有第三種場景需要開發(fā)人員使用其他策略保證冪等性:
>>SELECT col1 FROM tab1 WHER col2=2馍刮,無論執(zhí)行多少次都不會改變狀態(tài)信夫,是天然的冪等。
>>UPDATE tab1 SET col1=1 WHERE col2=2,無論執(zhí)行成功多少次狀態(tài)都是一致的静稻,因此也是冪等操作警没。
>>UPDATE tab1 SET col1=col1+1 WHERE col2=2,每次執(zhí)行的結果都會發(fā)生變化振湾,這種不是冪等的杀迹。

解決方案

###推薦方案: 結合redis與mysql的unique key
要求是支付一個訂單,必須插入一條支付流水押搪,order_id建一個唯一鍵树酪,unique key
所以你在支付一個訂單之前,先插入一條支付流水大州,order_id就已經(jīng)進去了
你就可以寫一個標識到redis里面去续语,set order_id payed,下一次重復請求過來了厦画,
先查redis的order_id對應的value绵载,如果是payed就說明已經(jīng)支付過了,你就別重復支付了
你再重復支付這個訂單的時候苛白,你寫嘗試插入一條支付流水,
數(shù)據(jù)庫給你報錯了焚虱,說unique key沖突了购裙,整個事務回滾就可以了
來保存一個是否處理過的標識也可以,服務的不同實例可以一起操作redis鹃栽。


### 1.樂觀鎖
如果只是更新已有的數(shù)據(jù)躏率,沒有必要對業(yè)務進行加鎖,
設計表結構時使用樂觀鎖民鼓,一般通過version來做樂觀鎖薇芝,
這樣既能保證執(zhí)行效率,又能保證冪等丰嘉。例如:
UPDATE tab1 SET col1=1,version=version+1 WHERE version=#version#
不過夯到,樂觀鎖存在失效的情況,就是常說的ABA問題饮亏,
如果version版本一直是自增的就不會出現(xiàn)ABA的情況耍贾。

### 2.防重表
使用訂單號orderNo做為去重表的唯一索引,每次請求都根據(jù)訂單號向去重表中插入一條數(shù)據(jù)路幸。
第一次請求查詢訂單支付狀態(tài)荐开,當然訂單沒有支付,進行支付操作简肴,無論成功與否晃听,
執(zhí)行完后更新訂單狀態(tài)為成功或失敗,刪除去重表中的數(shù)據(jù)。
后續(xù)的訂單因為表中唯一索引而插入失敗能扒,則返回操作失敗佣渴,直到第一次的請求完成(成功或失敗)赫粥。
可以看出防重表作用是加鎖的功能观话。

### 3.分布式鎖
這里使用的防重表可以使用分布式鎖代替,比如Redis越平。
訂單發(fā)起支付請求频蛔,支付系統(tǒng)會去Redis緩存中查詢是否存在該訂單號的Key,
如果不存在秦叛,則向Redis增加Key為訂單號晦溪。
查詢訂單支付已經(jīng)支付,如果沒有則進行支付挣跋,支付完成后刪除該訂單號的Key三圆。
通過Redis做到了分布式鎖,只有這次訂單訂單支付請求完成避咆,下次請求才能進來舟肉。
相比去重表,將放并發(fā)做到了緩存中查库,較為高效路媚。
思路相同,同一時間只能完成一次支付請求樊销。

### 4.token令牌
這種方式分成兩個階段:申請token階段和支付階段整慎。
第一階段,在進入到提交訂單頁面之前围苫,需要訂單系統(tǒng)根據(jù)用戶信息向支付系統(tǒng)發(fā)起一次申請token的請求裤园,
支付系統(tǒng)將token保存到Redis緩存中,為第二階段支付使用剂府。
第二階段拧揽,訂單系統(tǒng)拿著申請到的token發(fā)起支付請求,支付系統(tǒng)會檢查Redis中是否存在該token腺占,
如果存在强法,表示第一次發(fā)起支付請求,刪除緩存中token后開始支付邏輯處理湾笛;
如果緩存中不存在饮怯,表示非法請求。
實際上這里的token是一個信物嚎研,支付系統(tǒng)根據(jù)token確認蓖墅,你是你媽的孩子库倘。
不足是需要系統(tǒng)間交互兩次,流程較上述方法復雜论矾。

### 5.支付緩沖區(qū)
把訂單的支付請求都快速地接下來教翩,一個快速接單的緩沖管道。
后續(xù)使用異步任務處理管道中的數(shù)據(jù)贪壳,過濾掉重復的待支付訂單饱亿。
優(yōu)點是同步轉(zhuǎn)異步,高吞吐闰靴。
不足是不能及時地返回支付結果彪笼,需要后續(xù)監(jiān)聽支付結果的異步返回。

###狀態(tài)機冪等
在設計單據(jù)相關的業(yè)務蚂且,或者是任務相關的業(yè)務配猫,肯定會涉及到狀態(tài)機(狀態(tài)變更圖),
就是業(yè)務單據(jù)上面有個狀態(tài)杏死,狀態(tài)在不同的情況下會發(fā)生變更泵肄,一般情況下存在有限狀態(tài)機,
這時候淑翼,如果狀態(tài)機已經(jīng)處于下一個狀態(tài)腐巢,這時候來了一個上一個狀態(tài)的變更,理論上是不能夠變更的玄括,
這樣的話冯丙,保證了有限狀態(tài)機的冪等。
注意:訂單等單據(jù)類業(yè)務惠豺,存在很長的狀態(tài)流轉(zhuǎn),一定要深刻理解狀態(tài)機风宁,對業(yè)務系統(tǒng)設計能力提高有很大幫助 洁墙。
token令牌解決接口冪等性問題.png

冪等性接口的不足

增加了額外控制冪等的業(yè)務邏輯,復雜化了業(yè)務功能戒财;
把并行執(zhí)行的功能改為串行執(zhí)行热监,降低了執(zhí)行效率。

因此除了業(yè)務上的特殊要求外饮寞,盡量不提供冪等的接口孝扛。

參考資源
http://www.reibang.com/p/37cad53375db
http://www.reibang.com/p/3fc3646fad80

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市幽崩,隨后出現(xiàn)的幾起案子苦始,更是在濱河造成了極大的恐慌,老刑警劉巖慌申,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陌选,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機咨油,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門您炉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人役电,你說我怎么就攤上這事赚爵。” “怎么了法瑟?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵冀膝,是天一觀的道長。 經(jīng)常有香客問我瓢谢,道長畸写,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任氓扛,我火速辦了婚禮枯芬,結果婚禮上,老公的妹妹穿的比我還像新娘采郎。我一直安慰自己千所,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布蒜埋。 她就那樣靜靜地躺著淫痰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪整份。 梳的紋絲不亂的頭發(fā)上待错,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音烈评,去河邊找鬼火俄。 笑死,一個胖子當著我的面吹牛讲冠,可吹牛的內(nèi)容都是我干的瓜客。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼竿开,長吁一口氣:“原來是場噩夢啊……” “哼谱仪!你這毒婦竟也來了?” 一聲冷哼從身側響起否彩,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤疯攒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后列荔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卸例,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡称杨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了筷转。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姑原。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖呜舒,靈堂內(nèi)的尸體忽然破棺而出锭汛,到底是詐尸還是另有隱情,我是刑警寧澤袭蝗,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布唤殴,位于F島的核電站,受9級特大地震影響到腥,放射性物質(zhì)發(fā)生泄漏朵逝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一乡范、第九天 我趴在偏房一處隱蔽的房頂上張望配名。 院中可真熱鬧,春花似錦晋辆、人聲如沸渠脉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芋膘。三九已至,卻和暖如春霸饲,著一層夾襖步出監(jiān)牢的瞬間为朋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工厚脉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留习寸,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓器仗,卻偏偏與公主長得像融涣,于是被迫代替她去往敵國和親童番。 傳聞我的和親對象是個殘疾皇子精钮,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 作者:滌生_Woo鏈接:http://www.reibang.com/p/6e9e4156ece3 本篇文章篇幅...
    Fi的學習筆記閱讀 1,708評論 0 4
  • Web 頁面的實現(xiàn) Web 基于 HTTP 協(xié)議通信 客戶端(Client)的 Web 瀏覽器從 Web 服務器端...
    毛圈閱讀 1,082評論 0 2
  • 國家電網(wǎng)公司企業(yè)標準(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 10,958評論 6 13
  • 主人好久回一次家,他又要出差了剃斧,臨走前轨香,他把窗戶打開了。 每個下午幼东,總有風吹過臂容,窗簾像個小孩科雳,瘋狂地抖動它的身體。...
    背道閱讀 163評論 0 1
  • 懲罰的后果 懲罰會制止孩子得不良行為脓杉,至少是暫時制止糟秘。正因為這一點,大人們可能認為自己贏得了管教孩子得許多戰(zhàn)斗球散。然...
    愛心語家庭教育薛輝閱讀 163評論 0 0