2013-10-16 227 views
10

我已經開始設計一個RESTful API,並且正在考慮如何處理身份驗證。我想使用某種身份驗證令牌,但無法使用類似的基礎架構的OAuth,因此我必須自己處理它。在RESTful API中存儲身份驗證令牌的位置

一個對這個API的要求是它必須具有良好的性能,足以處理請求的高容量纔會有規模的需要;我關心的是如何在每個請求上儘可能少地驗證令牌(完整性,到期時間,IP地址等)所需的時間。

我想令牌應該某種哈希值,而不是包含用戶信息的加密字符串,因爲解密時間將是沉重的。

我讀過我可以將令牌存儲在內存散列表中,其中的關鍵是令牌,值是處理請求所需的用戶信息,但是如何在集羣環境中完成此項工作哪裏會有每個「節點」的哈希表?

我應該把令牌上的數據庫表的命中DB每次也可手動處理過期的門票保留?

也許它不是一個問題是重要的,但我使用Spring MVC中的問題的REST API。

在此先感謝。

+0

[REST API認證令牌]的可能重複(http://stackoverflow.com/questions/7919533/rest-api-authentication-tokens) – mayabelle

+0

@mayabelle感謝您的反饋。我不認爲這篇文章涵蓋了我的需求。我的問題是:如果我使用散列表或類似(我可能會使用Google Guava定時緩存),我如何在NLB環境中共享緩存?每次我必須檢查代幣還是有更好的方法時,我是否應該使用數據庫來存儲代幣並在數據庫中進行搜索? – Nicola

回答

3

我假設你使用https,因此所有的流量都被加密。我會建議以下原則之一。

基本身份驗證

您可以請求的Authorization頭添加憑據。這個證書是用Base64編碼的(見下文)。這個證書可以在每個請求上發送,然後用你的數據庫進行檢查。爲了讓這個更快,更少的IO密集,你仍然可以使用緩存。一旦我實現了這樣一個沒有緩存的API,並且每秒能夠處理數千個請求。

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== 

授權令牌

有實現與令牌你的想法不同的方式。一個常見的問題是每個API用戶都有自己的令牌,通常稱爲API密鑰,它永不過期。另一個是你首先必須授權(基本認證),然後得到一個過期的令牌。然後這一個被用作api密鑰一段時間。

無論哪種方式,你必須決定是否使用高速緩存與否。我會保持簡單,並進行基本身份驗證,並每次檢查數據庫。幾乎每個框架都對這種方法有很好的支持,因爲它很簡單。如果這會導致性能問題(我會推薦性能測試),嘗試將您的憑證添加到JPA緩存中。如果你想實現一些使用過期令牌,可以看看Infinispan。

5

我同時使用一個內存中緩存和數據庫高速緩存解決我的問題。以下是我的解決方案的總結,可以幫助任何人完成相同的任務。

  • 用戶登錄,並在那一刻生成一個唯一的密鑰併發回給用戶。
  • 登錄令牌(基本上是一個帶有某些處理的GUID)也存儲在數據庫表中,其中包含exipiration等附加信息以及用戶的信息和角色。相同的信息段也存儲在存儲器中(谷歌番石榴哈希表,其中該令牌是關鍵)
  • 令牌必須與授權令牌每個API調用作爲沿建議@ipa
  • 服務器代碼檢查是否被傳遞令牌在其內存緩存中,否則用戶信息已經可用(例如,api調用在羣集中的另一個節點上完成)令牌在令牌db中搜索一旦找到令牌,您可以檢查到期,角色等等...

這給予了良好的性能和安全級別,令牌可以用任意任意字母即使是相對較慢的,因爲您不必在每次api調用時重新計算它。這也適用於可以水平放大的無狀態服務。

+1

你如何在客戶端存儲令牌?在內存中,cookie,本地存儲?另外,我如何防範XSS和CSRF? – YarGnawh

+0

@YarGnawh現在我剛剛創建了服務器端Web服務RESTApi,我還沒有一個Web應用程序。無論如何,我爲wep應用做了一些測試,基本上我所做的是重寫Spring安全篩選器以避免使用會話並將我的身份驗證令牌存儲在用戶的Cookie存儲中。我沒有測試CSRF保護,但是通過這種方式使用spring安全性,即使使用像AngularJS這樣的js前端框架,您也應該可以輕鬆利用其CSRF功能。 – Nicola

+0

爲什麼不直接將令牌存儲在像redis這樣的共享內存緩存中?這也很容易處理到期。 – splinter123

0

您可以在Redis中存儲令牌。如果您要將其存儲在數據庫中,請確保優化服務器(如果您正在管理它)進行讀取操作。我也有幾個人在使用關鍵值存儲的實現。哈希表也是個好主意。