1. Cookie和seesion
1.1 cookie
定義:
指某些網站為了辨別用戶身份而儲存在用戶本地終端(Client Side)上的數據(通常經過加密)。
用途:
由於HTTP是一種無狀態的協議,服務器單從網絡連接上無從知道客戶身份。Cookie 一個典型的應用是當登錄一個網站時,網站往往會請求用戶輸入用戶名和密碼,並且用戶可以勾選“下次自動登錄”。如果勾選了,那么下次訪問同一網站時,用戶會發現沒輸入用戶名和密碼就已經登錄了。這正是因為前一次登錄時,服務器發送了包含登錄憑據(用戶名加密碼的某種加密形式)的 Cookie 到用戶的硬盤上。第二次登錄時,如果該 Cookie 尚未到期,瀏覽器會發送該 Cookie,服務器驗證憑據,於是不必輸入用戶名和密碼就讓用戶登錄了。
保存時間:
cookie的保存時間,可以自己在程序中設置。如果沒有設置保存時間,應該是一關閉瀏覽器,cookie就自動消失。
缺點:
- Cookie 會被附加在每個 HTTP 請求中,所以無形中增加了流量。
- 由於 HTTP 請求中的 Cookie 是明文傳遞的,所以安全性成問題,除非使用超文本傳輸安全協定。
- Cookie 的大小限制在 4 KB 左右,對於復雜的存儲需求來說是不夠用的。
1.2 session
Session是另一種記錄客戶狀態的機制,不同的是Cookie保存在客戶端瀏覽器中,而Session保存在服務器上。客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上。這就是Session。客戶端瀏覽器再次訪問時只需要從該Session中查找該客戶的狀態就可以了。
如果說Cookie機制是通過檢查客戶身上的“通行證”來確定客戶身份的話,那么Session機制就是通過檢查服務器上的“客戶明細表”來確認客戶身份。
session 也是類似的道理,服務器要知道當前發請求給自己的是誰。為了做這種區分,服務器就要給每個客戶端分配不同的“身份標識”,然后客戶端每次向服務器發請求的時候,都帶上這個“身份標識”,服務器就知道這個請求來自於誰了。對於瀏覽器客戶端,大家都默認采用 cookie 的方式,保存這個“身份標識”。
服務器使用session把用戶的信息臨時保存在了服務器上,用戶離開網站后session會被銷毀。這種用戶信息存儲方式相對cookie來說更安全。
缺陷:
如果web服務器做了負載均衡,那么下一個操作請求到了另一台服務器的時候session會丟失。
提示:Session的使用比Cookie方便,但是過多的Session存儲在服務器內存中,會對服務器造成壓力。
1.3 客戶端訪問服務器流程
- 首先,客戶端會發送一個http請求到服務器端。
- 服務器端接受客戶端請求后,建立一個session,並發送一個http響應到客戶端,這個響應頭,其中就包含Set-Cookie頭部。該頭部包含了sessionId。Set-Cookie格式如下,
Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure] - 在客戶端發起的第二次請求,假如服務器給了set-Cookie,瀏覽器會自動在請求頭中添加cookie
- 服務器接收請求,分解cookie,驗證信息,核對成功后返回response給客戶端

2.基於token的驗證方式
token驗證的特點
- 無狀態、可擴展
- 支持移動設備
- 跨程序調用
- 安全
2.1 token之前的認證
基於服務器的認證
我們都是知道HTTP協議是無狀態的,這種無狀態意味着程序需要驗證每一次請求,從而辨別客戶端的身份。
在這之前,程序都是通過在服務端存儲的登錄信息來辨別請求的。這種方式一般都是通過存儲Session來完成。
基於服務器認證的弊端
基於服務器驗證方式暴露的一些問題
1.Seesion:每次認證用戶發起請求時,服務器需要去創建一個記錄來存儲信息。當越來越多的用戶發請求時,內存的開銷也會不斷增加。
2.可擴展性:在服務端的內存中使用Seesion存儲登錄信息,伴隨而來的是可擴展性問題。
3.CORS(跨域資源共享):當我們需要讓數據跨多台移動設備上使用時,跨域資源的共享會是一個讓人頭疼的問題。在使用Ajax抓取另一個域的資源,就可以會出現禁止請求的情況。
4.CSRF(跨站請求偽造):用戶在訪問銀行網站時,他們很容易受到跨站請求偽造的攻擊,並且能夠被利用其訪問其他的網站。
2.2 基於Token的驗證原理
基於Token的身份驗證是無狀態的,我們不將用戶信息存在服務器中。這種概念解決了在服務端存儲信息時的許多問題。NoSession意味着你的程序可以根據需要去增減機器,而不用去擔心用戶是否登錄。
2.3 基於Token的身份驗證的過程如下:
- 用戶通過用戶名和密碼發送請求。
- 服務器端程序驗證。
- 服務器端程序返回一個帶簽名的token 給客戶端。
- 客戶端儲存token,並且每次訪問API都攜帶Token到服務器端的。
- 服務端驗證token,校驗成功則返回請求數據,校驗失敗則返回錯誤碼。

2.4 Token的優勢
- 無狀態、可擴展
在客戶端存儲的Tokens是無狀態的,並且能夠被擴展。基於這種無狀態和不存儲Session信息,負載負載均衡器能夠將用戶信息從一個服務傳到其他服務器上。tokens自己hold住了用戶的驗證信息。 - 安全性
請求中發送token而不再是發送cookie能夠防止CSRF(跨站請求偽造)。即使在客戶端使用cookie存儲token,cookie也僅僅是一個存儲機制而不是用於認證。不將信息存儲在Session中,讓我們少了對session操作。
token是有時效的,一段時間之后用戶需要重新驗證。 - 可擴展性
Tokens能夠創建與其它程序共享權限的程序。 - 多平台跨域
