2011-04-27 38 views
41

首先,應該爲應用服務的靜態頁面是登錄頁面嗎?backbone.js - 處理用戶是否登錄

其次,我的服務器端代碼是好的(它不會給任何用戶不應該能夠看到的數據)。但是,如何讓我的應用程序知道如果用戶未登錄,要返回登錄表單?

回答

14

我有一個後端調用,即我的靜態頁面(index.php)用來檢查當前用戶是否登錄的客戶端代碼。假設您有一個後端調用api/auth/logged_in,它返回HTTP狀態代碼200如果用戶登錄或以其他方式400(使用基於cookie的會話):

appController.checkUser(function(isLoggedIn){ 
    if(!isLoggedIn) { 
     window.location.hash = "login";  
    } 

    Backbone.history.start(); 
}); 

... 

window.AppController = Backbone.Controller.extend({ 

    checkUser: function(callback) { 
    var that = this; 

    $.ajax("api/auth/logged_in", { 
     type: "GET", 
     dataType: "json", 
     success: function() { 
     return callback(true); 
     }, 
     error: function() { 
     return callback(false); 
     } 
    }); 
    } 
}); 
+0

你會如何檢查是不斷收到任何數據之前?所以,當應用程序調用數據時,它會檢查它們是否已登錄。如果沒有,它將進入登錄頁面。 – Matthew 2011-04-29 14:48:48

+9

如果你想對後端的每一次調用進行檢查,你應該把它與你的後端代碼集成在一起。例如,如果用戶沒有對任何*呼叫進行認證,那麼你可以從後端返回一個'401 Unauthorized'或者你可以在客戶端捕獲的東西。 這樣,您不必在每次數據請求之前分別打電話來檢查授權。 在這種情況下,您可能必須重寫'Backbone.sync'方法來捕獲'401 Unauthorized'併發出一些事件,您可以使用它來檢測後端調用是否未經授權。 – Sam 2011-04-29 17:37:25

+1

請仔細閱讀↓ – user2398029 2013-05-19 19:35:55

69

我使用會話概念來控制用戶登錄狀態。

我有一個SessionModel和SessionCollection這樣的:

SessionModel = Backbone.Model.extend({ 
    defaults: { 
     sessionId: "", 
     userName: "", 
     password: "", 
     userId: "" 
    }, 

    isAuthorized: function(){ 
     return Boolean(this.get("sessionId")); 
    } 

}); 

在應用程序啓動,我初始化一個全局變量,activeSession。開始時,這個會話是未經授權的,任何綁定到這個模型實例的視圖都可以相應地渲染在登錄嘗試時,我首先通過使會話無效退出。

logout = function(){ 
    window.activeSession.id = ""; 
    window.activeSession.clear(); 
} 

這將觸發任何視圖,監聽activeSession,並將我的主視圖進入登錄模式,它將提出登錄提示。然後我得到了用戶的用戶名和密碼,並把它們放在這樣的activeSession:

login = function(userName, password){ 
    window.activeSession.set(
     { 
      userName: userName, 
      password: password 
     },{ 
      silent:true 
     } 
    ); 
    window.activeSession.save(); 
} 

這將通過backbone.sync觸發更新到服務器。在服務器上,我設置了會話資源POST操作,以便它檢查用戶名和密碼。如果有效,它會填寫會話上的用戶詳細信息,設置唯一的會話ID並刪除密碼,然後發回結果。

然後,我的backbone.sync被設置爲將window.activeSession的sessionId添加到對服務器的任何傳出請求。如果會話Id在服務器上無效,它將發回一個HTTP 401,該HTTP 401會觸發註銷(),導致顯示登錄提示。

我們還沒有完成實現,所以可能會出現邏輯錯誤,但基本上,這是我們如何處理它。另外,上面的代碼不是我們的實際代碼,因爲它包含更多的處理邏輯,但它是它的要點。

+0

我其實已經改變了一下行爲。我知道通過sessionCollection.create()創建新的會話,然後觸發任何視圖都可以收聽的全局可用loginSuccess消息。 – 2011-05-09 20:55:06

+0

你的方法聽起來不錯。任何機會,你可以分享你的更新代碼的要點? :) – dbau 2012-04-26 08:13:25

+0

不幸的是,由於後端存在問題(我們希望在後端使用現成的身份驗證系統),我們將此解決方案從單獨的身份驗證機制(現在基於Cookie)移開了。 – 2012-04-26 11:58:01

-14

我認爲你應該做這個服務器只片面...有得到它砍死單元,除非你有某種神奇的API的響應它

+8

你應該把它做成服務器端,但如果你不依賴它,檢測客戶端上的登錄狀態沒有任何問題。 – 2011-12-29 07:10:52

2

我想你不應該只控件的HTML的很多機會顯示還可以控制顯示數據。因爲用戶可以使用Firefox來改變你的JavaScript代碼。

有關詳細信息,您應該在用戶登錄後向用戶授予令牌,並且每次他或她訪問您的組件(如數據網格或樹等)時,頁面都必須獲取這些數據(可能是json)從你的web服務,web服務將檢查這個令牌,如果令牌不正確或過期,你不應該給用戶數據,而應該給出錯誤消息。因此,即使用戶使用螢火蟲更改js代碼,用戶也無法破解安全。

這可能對您有所幫助。