2013-02-17 66 views
6

我已經爲CakePHP應用程序構建了一個簡單的測試API,它將允許用戶從移動設備(或任何設備)登錄並獲得JSON響應。此API可用於PhoneGap中構建的移動應用程序。使用Sessions和令牌進行API身份驗證

的登錄方法看起來像這樣:

public function login() 
{ 
    if($this->request->is('post')) 
    { 
     // Use custom method in Model to find record with password params 
     $findUser = $this->User->findUser(
      $_POST['username_or_email'], 
      AuthComponent::password($_POST['password']) 
     ); 

     // If a user exists and matches params 
     if($findUser) 
     {       
      $this->User->id = $findUser['User']['id']; 

      $this->autoRender = false; 
      $this->response->type('json'); 
      $this->response->body(json_encode(array('authenticated'=>true,'message'=>__('You have been logged in successfully')))); 
     } 
     else 
     { 
      $this->autoRender = false; 
      $this->response->type('json'); 
      $this->response->body(json_encode(array('authenticated'=>false,'message'=>__('Username or password is incorrect')))); 
     } 

    } 
    else 
    { 
     $this->autoRender = false; 
     $this->response->type('json'); 
     $this->response->body(json_encode(array('message'=>'GET request not allowed!'))); 
    } 
} 

的移動設備(或API的用戶)可以發送自己的登錄信息,然後他們得到的JSON請求爲真或假的認證。 這個布爾值不是用來給用戶的訪問權限,而是告訴移動應用程序他們是否可以看到某些屏幕,並且他們只有獲得數據或者如果會話存在就可以發送數據!

就像剛纔陳述的那樣,它們實際上也是在設備上登錄到API本身,所以如果他們直接訪問網站(來自該設備),他們將會有一個會話並看到相同的JSON響應。

因此,基本上用戶在與服務器通信的設備上的會話持續時間內保持登錄狀態。這與需要爲每個請求傳遞的令牌不同,因爲在此示例中它們具有會話。

現在的問題...

  1. 是它的做法對於用戶是壞「實際上」登錄到API 與會話如上所示?它似乎是處理設備身份驗證的最安全方式,因爲它使用與直接Web根相同的邏輯。

  2. 我已經看到了一些API使用的訪問令牌,而不是這我也 實現(用戶得到他們的令牌,而不是返回布爾 並沒有創建會話)。但從我可以告訴,這似乎 喜歡更多的工作,然後我需要檢查訪問令牌對 用戶每次請求時記錄。

+0

這是CakePHP的一個很好的REST API插件。也許你可以從https https://github獲得一些指針。com/kvz/cakephp-rest-plugin(它使用令牌與Auth組件結合使用) – 2013-02-21 13:10:07

+0

是的,我以前見過,但我一直在尋找自己開發的東西。但他們也使用'$ this-> Auth-> login()',它實際上將用戶登錄到系統並創建一個會話。 – Cameron 2013-02-21 16:12:19

+0

是的。我正在使用它,但是覆蓋了beforeFilter中的一些功能,以不同的方式使用不同的令牌進行授權,同時仍然保留了插件和CakePHP給我的一些automagick。 – 2013-02-21 18:32:28

回答

2

Restful API限制使用會話並保存系統狀態。每個請求都必須登錄用戶。 訪問tokes是偉大的,但也需要額外的處理。
最簡單的方式是通過HTTP基本認證(「授權」 HTTP標頭)發送授權數據
http://www.httpwatch.com/httpgallery/authentication/
移動應用程序可以很容易地做到這一點,很容易添加此頭爲每個請求API。
在服務器端:

$username = env('PHP_AUTH_USER'); 
$password = env('PHP_AUTH_PW'); 

而且過程與此數據用戶登錄在ApiAppController-> beforeFilter()

+0

不確定您的意思是「限制」,因爲我可以處理所有請求,並在移動設備存在會話後正常發送數據。因此,如果用戶已經登錄,他們現在將擁有一個會話,並且能夠像預期的那樣訪問整個API中的方法,而無需對每個請求進行身份驗證。所以沒有看到使用基本身份驗證和訪問令牌的優點,除非我錯了? – Cameron 2013-02-20 17:47:57

+0

當然,在API或其他地方使用會話沒有PHP限制。但根據廣泛傳播的API建議稱爲「Restful API」 - API必須是無狀態的,這意味着它不會在任何2個請求之間存儲任何內容。這裏是關於它的問題 - http://stackoverflow.com/questions/8711044/is-it-good-to-implement-rest-api-using-sessions – Swayok 2013-02-20 20:58:04

+0

這裏是關於REST - http://en.wikipedia。組織/維基/ Representational_state_transfer。我建議你堅持這個建議 – Swayok 2013-02-20 21:01:09

3

讓您的應用登錄每次,而與登錄通對作爲Swayok最後建議。當您登錄時,服務器會生成一個令牌並將其返回給客戶端。客戶端在發出請求時會使用此令牌。在每個請求上,服務器檢查令牌是否有效,如果是,則執行請求。

這與會話的工作方式非常相似,服務器端框架在內部對其進行管理,並且這些令牌會不時過期。然而,正如Swayok正確指出的那樣,您不希望會話主要是因爲您是RESTful API應該沒有狀態。您可以獲得相同的實用程序,無需存儲關於用戶的任何用戶特定數據,也不會在每次請求時記錄用戶。

下面是關於這個good article,或者你可以嘗試Facebook的圖形API資源管理器,看看它在行動

+1

注 - 使用令牌時,您需要通過GET或POST將它們添加到每個請求中,並添加對每個請求進行一些附加編程。通過使用基本身份驗證標頭 - 您只需要製作一種方法爲任何請求添加標頭,並使用該方法與服務器進行通信(即使用戶尚未登錄,也可以使用該方法)。實際上你可以通過Basic Auth header =)以用戶登錄的形式傳遞一個令牌,有時你不需要一個可以過期的令牌=)什麼樣的方式可以選擇 - 取決於你和你的應用程序的需求=) – Swayok 2013-02-26 12:26:25

23

編輯
爲了清楚起見,我不是REST的支持者,我是一個支持RESTful/REST的服務。如果你看看互聯網上的所有API,很少有人真正堅持一種標準。無論您選擇什麼方案都取決於您的具體問題空間。只是儘量是安全的,使用直觀的設計選擇(即不名稱的服務「貓」,如果它返回有關「狗」的信息)
末編輯

它是基於REST API的很好的做法來管理一些會話/標記方案的形式。真正的理想(至少在我看來,這個問題上有許多學派)設置涉及滾動令牌。

如果您完全擔心您的API的安全性,那麼應該將權限管理出您的數據庫層。是的,這會造成一個瓶頸,但這實際上是一件好事。每次需要擊中數據庫來驗證客戶端令牌時,都會在整個過程中增加額外的步驟。這會降低API,這在安全的系統中實際上是需要的。你不希望惡意個人能夠每秒擊中你的API 3000次,你希望他們的請求掛起一段(有點)相當大的一小部分時間。

這與MD5散列算法類似。他們中的許多人重新計算了幾百次哈希,並在兩者之間進行了隨機暫停。這有助於防止惡意客戶端試圖暴力破解密碼(通過對密碼字符串的每個變體進行測試需要更多時間)。這同樣適用於您的API。

另一個好處是,如果你的DO有一個反覆嘗試登錄的惡意用戶,如果你是從數據庫層管理他們,那麼你可以用紅旗標出他們的IP地址/用戶名/什麼 - 具備-你,只是在步驟放棄他們的請求1.

無論如何,對於一個建議的過程(與滾動令牌,你可以切出的這部分如果它似乎矯枉過正,但是這是海拉安全):

  1. 用戶點擊'登錄'服務,這需要用戶名/密碼,並返回兩個令牌,一個私人訪問令牌和一個公共請求t令牌(服務器將這些令牌存儲在數據庫中)。
  2. 客戶端存儲在一個安全的地方,這些令牌
  3. 用戶訪問另一個端點推/拉一些數據
    • 請求包括時間戳
    • 請求中包含公共請求令牌
    • 請求中,包含一個訪問令牌=>該令牌應該是由時間戳字符串連接到私有訪問令牌字符串結尾的字符串的MD5哈希
  4. 服務器將P ublic請求令牌,使用它來查找已存儲
    • 的服務器採用的私人訪問令牌,並在時刻字符串會連接,然後又把這個字符串的MD5
    • 私人訪問令牌如果新的訪問令牌匹配客戶端發送服務器HURRAY的客戶端,這個客戶端被驗證,所以推/拉數據
  5. (可選)服務器爲每個請求生成新的令牌,並將它們返回給客戶端。這樣每個事務都會使舊的令牌無效,如果發生某種中間人攻擊,如果VALID用戶已經完成了他們的請求,那麼惡意用戶現在擁有無效的令牌,並且不能開始搞亂你的API。該方案試圖確保惡意用戶不會期望攔截服務器和客戶端之間的單一通信,並且仍然可以訪問系統。如果他們這樣做,那麼REAL用戶應該立即獲得無效的令牌。然後應該觸發他們的API客戶端重新登錄'登錄'服務,獲得新的有效令牌。這再次將惡意用戶踢出系統。

該方案不是100%安全的,不會有用戶訪問系統。通過在令牌上添加過期日期可以使其更安全。此方案還具有額外的好處,即您可以爲用戶/令牌分配特定的權限(即只讀訪問,只能看到某些終端點等)

這不是您唯一可以做事情的方式,我想查找其他的身份驗證方案,並採取你想要什麼,從他們每個人(OAUTH是一個良好的開端,那麼我想看看Facebook的/ Twitter的/ Instagram的)

+0

你的過程這裏解釋稱爲HMAC。爲進一步閱讀http://en.wikipedia.org/wiki/Hash-based_message_authentication_code – 2015-04-16 17:21:52

0

回答您的問題

  1. 只要您在應用程序關閉時關閉會話並在需要時重新創建會話,這不是一個壞習慣。它們就像他們在瀏覽器中登錄他們所知道的一樣,並且具有登出的功能,但是應用程序上也應該有相同的功能,否則他們可能會關閉應用程序,但實際上並未結束會話。您可以通過多種方式處理此問題,方法是讓他們在關閉應用程序時註銷自動檢查
  2. 令牌是進行上述操作的增強方式,但您必須考慮令牌在傳輸時的安全程度,服務器需要驗證令牌對每個請求。你已經說過,看起來更多的工作是如此,如果你有更多的工作,並且如果你有時間或金錢的限制,並尋找答案,說會話風格是否會在將來危害你的應用程序,只要你控制會話並且不會結束會話而離開用戶。如果你有時間,然後實現令牌,你會喜歡它。
相關問題