2011-08-31 94 views
22

我正在編寫一個具有一些ACL要求的Web應用程序:用戶可以對某些項目進行更改,某些項目可能由多個用戶編輯,管理員可以編輯任何內容並且管理員可以編輯她的組織內的所有內容等。授權應該是模型還是控制器的一部分?

我正在使用Play!框架,以及Secure模塊的外觀,似乎將授權問題放在控制器中。但是,在我看來,授權問題是業務邏輯的一部分,因此應該在模型中。此外,我開始在控制器中看到需要重構的重複邏輯。

另一方面,向模型添加授權意味着我必須有某種方式從模型中獲取當前用戶,這似乎不正確。或者,我可以爲每個模型方法添加一個「current_user」參數,但似乎更糟。

那麼常用的做法是什麼?可以/我應該將授權碼放在模型中,還是放在控制器中?

回答

14

我認爲這是一個灰色地帶。有人可能會爭辯說,用戶訪問是HTTP世界和麪向對象世界之間映射的一部分。這是控制器的目的(因此大量使用靜態)來轉換傳入的請求,準備好處理域模型上的業務規則。

我建議控制器邏輯絕對是控制對模型訪問的正確位置,尤其是當它主要在註釋級別進行管理時,並且認證被抽象爲安全類。

+7

那麼,它是灰色地帶,還是絕對正確? :) – itsadok

+3

在我看來,我認爲這是絕對正確的,但是,這是一個灰色地帶,因此可以進行解釋。那麼,這取決於你是否同意我的解釋:o) – Codemwnci

4

在大多數情況下,安全性應該是模型上方的一個(或更多)層。安全是它自己的一個域,限制對低層的訪問。

我不認爲安全應該在控制器級別完成。

在我看來,這應該是一個:

查看 - >控制器 - >安全 - >模型

安全層可以是外觀還是在模型的代理,保護訪問,但對控制器透明。但是,如果要根據用戶的訪問權限修改視圖,則可能必須在控制器級別進行一些檢查(例如,在ViewModel上設置CanEdit布爾屬性的值)。

+0

你在混合安全和授權。安全問題必須在應用程序的每個層面上處理 - 請參閱:縱深防禦。問題是「授權屬於哪裏?」,而不是安全性。 –

1

授權不應該是控制器或域模型的一部分。

相反,它應該在服務層。

控制器應該充當調度程序並在HTTP和應用程序服務之間進行委託。 這是編排發生的應用程序服務。這是放置授權的最佳位置。

假設用戶A被授權訪問來自域X的數據,但未被授權訪問來自域Y的數據的讀取訪問。如果授權被放置在控制器中,則用戶A在控制器X中獲得授權,並且通過服務呼叫可以訪問來自域Y的數據,這不是我們所期望的。

由於域模型在服務層上相互通信,因此最好將授權放在同一級別上。

0

我在這個階段,並打算通過以下方式來處理這個問題:

  • 沒有形式通過JS驗證,而不是通過HTTPS AJAX

  • 一個AJAX的PHP類

  • 表格數據發送到模型作爲其數據的具體驗證
    常見類型,如電子郵件和密碼(可能assoc數組驗證將被其他類重用,所以這是definat只是一個示範區)。

  • 如果沒有錯誤在用戶表中的憑據的查找電子郵件傳遞到與認證
    類型如登錄/註冊/口令的控制器/
    密碼憑證重置

  • 控制器然後產生所需的輸出視圖或設置用戶登錄會話等

這是基於在Laravel,但我有自己的庫作爲希望它獨立laravel的,只是鬆散的,基於此VITA l要求。

問題的關鍵在於模型將所需憑證作爲數據查找,然後發送給Controller,因爲它不關心應該如何處理它。我認爲這是使這個領域成爲每個組件之間的明確責任的唯一途徑。

0

我與MVC框架個人的經驗,我會說:

  1. 型號是代表數據庫表中的對象應該是 純粹,不應包含任何額外的邏輯。
  2. 控制器是做決定的地方和其他 定製邏輯,所以授權應該在控制器中。它可以設計一些鉤子,可以檢查用戶是否被授權 或不在所有需要的地方,所以你不會有代碼重複幹。

  3. ,如果你使用的是典型的 REST架構給權限的用戶,最好的辦法是做一個標記,將其保存在DATABSE和 客戶端,並驗證在每次請求該令牌。如果您使用的是 網絡瀏覽器應用程序,則可以使用服務器端會話進行授權( 更容易)。

所以我的建議是保持授權邏輯在控制器。

相關問題