2013-04-27 85 views
11

我目前正在爲我的RESTful API實現OAuth 2.0體系結構。使用Redis檢查訪問令牌的每個請求

對於每個請求,我都在HTTP標頭中爲所有客戶端設置授權承載令牌,以製作授權請求。

Authorization: Bearer sdflksd3r4823vkn95-03850432 

據我所知,通常只在API中接受令牌直到過期日期。但是,如果用戶想要令牌撤銷,我需要採用一種方法來檢查每個請求的令牌狀態。

所以我要去數據庫來檢查每個HTTP請求思考。我有一種感覺,由於性能原因,這不會很好地擴展。

所以我想知道是否像Redis這樣的解決方案適合於訪問令牌狀態的快速單一讀取?

回答

9

使用令牌的HMAC的要點是,服務器可以快速驗證它,而不用調用任何外部數據存儲(例如Redis,MySQL等)。由於沒有共享狀態(驗證令牌的所有信息是令牌本身和HMAC的密鑰),這具有向多個服務器很好地擴展的額外好處。

如果你有一個撤銷令牌的黑名單,那麼類似Redis的東西可能會很好(儘管比每個令牌驗證的遠程調用還要慢)。設置正確,Redis實例和API服務器之間的延遲時間較短,您應該在每個請求中看到< 10ms。

紅利:另一種加快速度的方法是使用Bloom filter來處理被拒絕的API請求的高速緩存。這樣,如果布隆過濾器將請求標記標記爲可能被撤銷,那麼您只能訪問Redis。請注意,由於這是另一層緩存,因此當令牌被拒絕時,您必須更新布隆過濾器的狀態。

+0

我絕對考慮一個布隆過濾器。雖然我也想知道它是否使用單例緩存是一個可行的選項 – 2013-04-27 01:45:08

+1

如果你只有一臺服務器,那麼你有更多的選擇,因爲你只需要在一個地方維護狀態。像Redis這樣的外部服務器維護狀態允許您擁有多個API服務器。單身人士只適用於你有一臺服務器的情況。另一種選擇是分佈式地圖(連貫,Hazelcast等)。如果令牌的到期時間相對較短,那麼您也可以在分佈式映射到期時從分佈式映射中刪除,以減小它的大小。 – sehrope 2013-04-27 01:49:22

+0

優秀的答案。非常感謝! – 2013-04-27 01:57:19

2

我爲自己做了類似的事情。
對於令牌語法和加密,我建議你使用JWT,這是一個很好的標準。
可以使用redis來存儲一個令牌/用戶標識,因爲我們可以設置一個過期值。
此外,我在中間插入一個布隆過濾器,但我比sehrope建議相反的方式做它:我存儲在登錄的所有令牌通過布隆過濾器,因此,如果令牌不存在是絕對無效;否則可能是正確的,但我必須檢查Redis以確定;但現在我遇到了一個問題:如果我想擴展我的身份驗證系統,我需要一個身份驗證服務器之間的負載均衡器。 恕我直言,使用布隆過濾器來創建一個黑名單是不正確的:如果我在布隆黑名單過濾撤銷和錯誤的令牌,如果該項目不列入黑名單bloom過濾器返回false(我必須檢查它在redis後端授權);否則,如果一個元素存在(列入黑名單),我必須在redis上檢查它,因爲布隆過濾器的真實響應可能是誤報。

+0

我實際上在我的AngularJS網站上使用了存儲在sessionStorage中的JWT令牌。每當瀏覽器應用程序關閉時,他們都必須登錄。這也是30分鐘到期時間,用戶將不得不重新簽發另一個令牌。我只是簡單地使用redis來記錄它,它可以讓我很快找到令牌。 – 2014-05-04 04:20:11

6

我實現了類似的功能來處理JWT生成的撤銷令牌。

我使用redis來設置過期令牌,因此令牌會自動從redis中刪除。我有一箇中間件來檢查redis提供的令牌。檢查full post here。希望它有幫助

相關問題