2013-01-10 145 views
22

我正在構建一個PHP REST API,該API將從JavaScript客戶端使用,並且在解決如何實現身份驗證和訪問方面存在一些問題。將會有多個應用程序將使用我將開發的JavaScript庫來與我的應用程序進行對話和交互。我將爲每個人提供API密鑰,所以這不是問題。JavaScript客戶端對REST API的授權和身份驗證

我開始感到困惑的是如何讓這些網站上的用戶對我的應用程序進行身份驗證。這個外部網站存儲我的用戶的帳戶和密碼信息似乎是個不錯的主意;所以,我想我應該讓我的JavaScript庫包含一個登錄窗口小部件,用於請求我的應用程序的用戶帳戶信息。

如果身份驗證在那裏成功,由於我正在使用REST API,因此我需要將檢索到的令牌存儲在客戶端Cookie或其他內容中,以便用戶無需再次登錄到我的應用程序在外部網站的每個頁面上。但是,如果用戶從外部站點註銷,然後另一個用戶從同一瀏覽器登錄,會發生什麼情況?就我的JavaScript庫而言,舊用戶仍然會登錄到我的應用程序中,因爲Cookie /令牌還沒有過期 - 當前一個用戶的會話結束時,如何清除cookie?或者,我在這裏完全脫離正確的道路嗎?

所以,我想過程會是這樣的:

埋在這裏
var token; // Some hashed string containing an expiration date and user id 
var apiKey = '123abc'; 

// Read the cookie and check if it already contains the token 
token = readCookie('token'); 
if (token == '') { 
    // get username and password from user through some prompt 

    var request_data = {apiKey: apiKey, user: username, pass: password}; 
    $.post('https://service.com/api/user/login', request_data, function(data) { 
     token = data; 
     document.cookie = "token=" + token; 
    }); 
} 

... 

var get_data = {apiKey: apiKey, token: token}; 
$.get('http://service.com/api/<object>', get_data, function(data) { 
    // Do something with data 
}); 

對不起,有幾個問題。我猜最主要的是如果我將令牌存儲到cookie中,如何確保在用戶註銷外部應用程序時將其清除?或者,如果我不應該將它存儲到cookie中,我如何讓客戶端知道用戶的狀態?

+0

我想你應該在你的js API中提供一些'login' /'logout'方法,你的客戶端(那些在應用程序中使用你的庫的站點)應該根據他們的本地登錄/註銷順序調用。如果他們不需要認證,恐怕你無法攔截一個用戶在同一個瀏覽器中(例如,在某個網吧)接替另一個用戶的時刻。 – Stan

回答

40

我建議您閱讀very good blog post關於保護RESTful API的安全。

(在情況下鏈接不起作用—它已經死了一次,並且必須從archive.org —檢索到的,我發現它似乎是一個PDF渲染這個頁面可以訪問這裏:https://www.ida.liu.se/~TDDD97/labs/hmacarticle.pdf

注意:我的回答是偏離主題,因爲上面的博客文章中提供的解決方案不是從Javascript客戶端安全的。實際上,它主要解釋如何在服務器端保護REST API。

+6

我讀過的第一件事並沒有以「如此使用OAuth」來結束......並且獎金非常直截了當,特別是如果您已經瞭解了基本密碼學結構的一小部分。很棒的發現。 – Kaganar

+5

如果您從JS客戶端使用HMAC,則客戶端應該擁有密鑰來簽署請求,從而將其公開化,這使得它無用。 –

+0

由於該鏈接現在已經多次下降,因此可能需要重新回顧這個答案,並將鏈接中的重要信息整合到答案本身中。您可以通過引用重要的位(使用blockquote格式)和/或通過彙總它們(使用您自己的單詞)來做到這一點。離開鏈接以提供上下文。我認爲這是值得的,因爲這已經被證明是多年來非常受歡迎的答案。 –

1

如果它是一個私有API(你有一個用戶表)從另一個主機名跨域到你自己的主機名,我同意上面的建議,並提出一個簡單的(SSL)登錄/註銷,可以給你的用戶(或帶走)來自你的域名的cookie。

如果是公共API(任何人都可以獲得API密鑰),我建議使用上面的答案在博客文章中的方法。

對於JavaScript客戶端,嘗試https://github.com/jpillora/jquery.rest,如有丟失,提交功能請求,或者如果你喜歡:)

8

「我在哪裏開始越來越困惑的是如何對這些網站的用戶進行身份驗證,以我的申請作出貢獻。這個外部網站存儲我的用戶的帳戶和密碼信息似乎是個不錯的主意;「-

使用REST APIs,處理此問題的最佳方法是使用您的客戶端(網頁,移動應用程序)通過您的域或外部通過用戶輸入的用戶憑據(在登錄頁面中)您將擁有一個登錄/註銷API來處理身份驗證

當登錄API進行身份驗證時,它會返回一個令牌單向散列可能是用戶首選項),它可以存儲在客戶端的加密cookie中,這樣,你的客戶端就不會直接處理用戶憑證,令牌設置爲只要你想要就過期。

對於所有後續的REST API調用,您的客戶端將提交此令牌以及對API的請求(與登錄/註銷API不同)。 API可能會檢查本地緩存(在REST服務器上)以查看這是否是有效的令牌。如果找到,則表示要求。否則,會引發錯誤。

如果用戶在令牌過期之前註銷,則登錄/註銷API將從本地緩存中刪除此令牌,並且您的客戶端需要刪除會話/ cookie。

這樣你的憑證永遠不會在客戶端傳遞。

當然,數據移動安全性也應該通過SSL和HTTP摘要來實現。