一起聊-聊token認證

互聯網概念的token認證,大抵是在RESTful API 流行後提出的,在開始token認證之前,我們先梳理下常見的互聯網認證機制。

一、HTTP Basic Auth

HTTP Basic Auth常見的有兩種:第一種就是最常見的,即我們在登陸一些web頁面時,會讓我們輸入用戶名密碼;另一種是將用戶名密碼信息通過base64這類算法變換成一條字符串在http請求頭中增加auth字段,再傳輸給服務端。

這個屬於最原始級的認證,缺點比較明顯,存在http頭中的密碼信息容易被抓包獲取,用戶名密碼後服務端後需要查詢數據庫裡的信息,進行比對信息,這也增加了服務器的負擔。

二、session+cookie模式

假設目前我們有一個查詢類的web站點,不可能查詢都要登陸一次,為解決一次登陸,可以在固定一段時間內都免登陸查詢,就出現了session+cookie模式,該模式是第一次登陸時使用HTTP Basic Auth,認證成功後,為避免每次都到數據庫裡校驗用戶名密碼信息,就在主機上存儲一份登陸的session信息,在本身cookie裡記錄對應的session信息,cookie裡同時保存expire time。

該模式優缺點都比較明顯:session信息需要額外的數據庫存儲,例如一般需增加redis、memached等應用。在多機負載時,需要考慮session共享;但好處也是明顯的,session信息統一管理,可以在服務端統一控制認證的過期時間或個別用戶的過期時間。

一起聊-聊token認證


三、簡單token認證

token認證最常用的應用場景就是查詢接口的調用(RESTful API),查詢接口的信息在沒有安全需求時,大家都可以通過get方法或post方法取得所需信息。但在有安全需要時一般需要認證後才能獲取所需的信息,這時候可以通過先能過HTTP Basic Auth,HTTP Basic Auth認證完成後,服務端返回給客戶端一個類似於UUID的唯一標識,我們稱之為token。該token一般可以在URL或head頭裡加入,如以下的常見的URL模式

http://api,361way.com/getinfo?token=xxxxx 或 http://api,361way.com/getinfo?t=xxxxx ,後面再加上相應的查詢信息,就可以獲取到相應的數據。

token的好處是服務端不需要存儲相應信息,但被不懷好意的人從中間獲取到該信息時,也容易被利用,非法獲取數據。

由於這個簡單的token返回串裡未返回相應的過期時間信息,如果想增強安全性,一般可以在服務端生成時配合時間戳生成,服務端在接收到client發來帶token的信息時,先檢測反解token獲取時間戳信息,如果該時間戳在超過某個時間點時,就認為過期,需要重新獲取。

四、OAuth認證

OAuth(開放授權)是一個開放的授權標準,允許用戶讓第三方應用訪問該用戶在某一web服務上存儲的私密的資源(如照片,視頻,聯繫人列表),而無需將用戶名和密碼提供給第三方應用。OAuth允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每一個令牌授權一個特定的第三方系統(例如,視頻編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth讓用戶可以授權第三方網站訪問他們存儲在另外服務提供者的某些特定信息,而非所有內容。

這個理解起來比較繞口,舉個例子,如很多網站上面有qq或微信登陸接口,qq或微信提供的就是OAuth認證。OAuth雖然名字很洋氣,其本質還是token認證,仔細研究下上面的話,是不是原理上和上面提到的簡單token認證類似,只不過其加了幾個callback函數而已

這裡以douban豆瓣網調用QQ的OAuth節口為例,其調用方式如下:

# 發起認證:
http://www.douban.com/leadToAuthorize
# 重定向到QQ認證,並指定回調:

http://www.qq.com/authorize?callback=www.douban.com/callback
# 返回授權碼,並callback到douban
http://www.douban.com/callback

五、JWT認證

JSON Web Token(JWT)是一個非常輕巧的規範。這個規範允許我們使用JWT在用戶和服務器之間傳遞安全可靠的信息。一個JWT實際上就是一個字符串,它由三部分組成,頭部(Header)、載荷(Payload)與簽名(Signature)。這裡只簡單說下理論,會另開博文深層討論。

Payload裡存放的是存儲簽發者、簽發時間、過期時間、一些數據信息的JSON格式的內容。

{ "iss": "Online JWT Builder",
"iat": 1416797419,
"exp": 1448333419,
"aud": "www.example.com",
"sub": "[email protected]",
"GivenName": "Johnny",
"Surname": "Rocket",
"Email": "[email protected]",
"Role": [ "Manager", "Project Administrator" ]
}

Header裡指定存放的是指定使用的協議JWT、加密簽名的類型,示例如下:

{
"typ": "JWT",
"alg": "HS256"
}

最後簽名就是將上面兩者的信息通過BASE64編碼,再加上密鑰信息,三者之間通過點號連接,就組合成的JWT token。可以對比簡單token和JWT的區別,兩者本質上都是token,只不過JWT在token裡多傳輸了一些信息。


分享到:


相關文章: