2012-09-05 117 views
1

我開始構建/設計一個新的單頁Web應用程序,並且確實希望主要在前端使用客戶端技術(HTML,CSS,JavaScript/CoffeScript),同時使用瘦REST API後端將數據提供給前端。已經出現的問題是關於JavaScript的安全性。例如,將會顯示某些鏈接和UI元素,這些元素將僅根據用戶所附加的角色和資源顯示。當用戶登錄時,它將進行一個REST調用,它將驗證憑據,然後返回一個json對象,該對象具有該用戶的所有權限並存儲在JavaScript對象中。JavaScript中的安全代碼

讓我們這段JavaScript代碼:

// Generated by CoffeeScript 1.3.3 
(function() { 
    var acl, permissions, root; 

    root = typeof exports !== "undefined" && exports !== null ? exports : this; 

    permissions = { 
    //data… 
    }; 

    acl = { 
    hasPermission: function(resource, permission, instanceId) { 
     //code…. 
    } 
    }; 

    root.acl = acl; 

}).call(this); 

下面這段代碼設置確保即使通過控制檯,沒有人可以修改變量的權限。這裏的問題是,因爲這是一個單頁面應用程序,我可能想更新權限而不必刷新頁面(也許他們添加了一條需要添加到他們權限的記錄)。我能想到這樣做的唯一方法是添加類似

setPermission: function(resource, permission, instanceId){ 
    //code… 
} 

到ACL對象但如果我這樣做,是不是意味着有人在瀏覽器控制檯還可以用它來添加權限自理,他們應該沒有。有什麼方法可以添加無法從瀏覽器控制檯訪問的代碼,但可以從JavaScript文件中的代碼訪問嗎?

現在,即使我可以防止上述問題,我仍然有一個更大的問題。不管是什麼,我要必須調用hasPermission功能然而,當它被宣稱這種方式,我可以在瀏覽器控制檯通過只是在做覆寫方法:

acl.hasPermission(resource, permission, instanceId){return true;} 

,現在我能看到的一切。有沒有辦法定義這種方法是一種用戶不能重寫它的方式(比如將其標記爲final或某物)?

需要注意的是,每個REST API調用也會檢查權限,即使他們要看到他們不應該做的事情,他們仍然無法做任何事情,並且REST API會對請求感到後悔由於權限問題。有人建議在服務器端生成模板,但我真的不喜歡這個想法,因爲它在前端和後端技術堆棧之間建立了非常強大的耦合。例如,無論出於何種原因,我們需要將PHP移植到Python或Ruby,如果模板是在JavaScript的客戶端上構建的,那麼我只需重新構建REST API,所有前端代碼都可以保留相同但不是如果我在服務器端生成模板的情況。

+1

只有使用客戶端安全代碼才能確保安全,您需要製作某種身份驗證令牌mecanism(從服務器獲取一個)並在請求安全資源時在服務器上進行檢查。 – Guillaume86

+0

在沒有閱讀你的問題的情況下說這些 - 只是思考 - 安全和javascript通常不會並存。這相當於你在門上放了一張「請勿打擾」標籤,希望沒有人走進去,但他們仍然可以這樣做。 – Duniyadnd

+0

保持登錄安全的唯一方法是在服務器端進行登錄。糾正我,如果我錯了。 – starbeamrainbowlabs

回答

4

不管你做什麼:你必須檢查服務器端的所有權限(在你的REST後端,如你所注意到的)。無論你跳過什麼環節,有人都可以進行他們不應該做的REST呼叫。

這有效地使您的客戶端安全系統進行了優化:您嘗試僅向用戶顯示允許的操作,並嘗試避免往返服務器以獲取允許的內容。因此,您並不需要關心用戶是否可以「破解」它:如果他們破壞了您的應用程序,他們可以保留這兩個部分。不會發生任何錯誤,因爲服務器不會讓他們執行他們未被授權的操作。

但是,我仍然以一種預期「拒絕訪問」作爲有效答案(而不是必須例外)的方式編寫客戶端代碼。響應可能有很多原因:如果登錄用戶的權限在瀏覽器處於打開狀態時發生更改,則客戶端的安全描述不再與服務器匹配,應該適當地處理該情況(顯示「對不起,這個操作是不允許的「,並重新加載安全描述,例如)。

2

永遠不要信任Javascript代碼或一般的前端。人們甚至可以修改代碼到達您的瀏覽器(嗅探器等)和大多數變量是訪問和修改反正之前...相信我:你永遠不會是在前端:)

安全總是檢查服務器端的憑據,從來沒有只在前端!

0

在現代瀏覽器中,可以使用Object.freezeObject.defineProperty來確保hasPermission方法不能被重新定義。

我還不知道如何解決setPermission的問題。也許最好只依靠服務器端的安全性,正如你所說的那樣。