2014-08-29 144 views
3

我在Rails中使用了cancan gem,但這可能比這更普遍。應用程序邏輯與授權

簡短介紹。在cancan,你定義授權這樣的:

can :read, Post 
can :manage, Post if user.is_admin? 
can :manage, Post do |post| post.author == user end 

這意味着,任何人都可以閱讀Post S,但只有作者和管理員可以管理(編輯/銷燬)他們。

現在我想更改我的應用程序邏輯,以便如果它有任何評論(除非您是管理員),則不能刪除您的帖子。它仍然易於使用(添加在上面代碼的結尾)cancan

cannot :destroy, Post do |post| post.comments.count > 0 && !user.is_admin? end 

,這意味着我可以使用下面的僞碼的視圖(HTML模板):

<h1><%=post.title%></h1> 
<p><%=post.text%></p> 
<%=link_to 'Edit', edit_post_path(post) if can? :edit, post%> 
<%=link_to 'Delete', delete_post_path(post) if can? :destroy, post%> 

我唯一的問題是將權限本身與應用邏輯混合起來是否合理?感覺那種骯髒的,但另一方面我需要打破乾燥,與應用程序中到處重複檢查(前端,API等)

<h1><%=post.title%></h1> 
<p><%=post.text%></p> 
<%=link_to 'Edit', edit_post_path(post) if post.can_be_edited? && can? :edit, post%> 
<%=link_to 'Delete', delete_post_path(post) if post.can_be_destroyed? && can? :destroy, post %> 

回答

1

我看不出有任何問題,替換該將與授權相關行爲的檢查放在您建議的地方。正如你所提到的,替代方案更糟糕。此外,這意味着某人可以輕鬆查看一個地點以查看Post的授權方案,這非常可取。另一種方法(在多個地方進行檢查)更難以維護和推理,更不用說更改必須在多個地方進行編輯,並且只是開發人員同時編輯它們的一個「紳士協議」,可以使它們保持一致同步中。

0

除了tmruss的評論,我想補充一點,你正在嘗試使用cancan稱爲外部化授權。這是一個很好的方法。您應該始終努力將授權邏輯與業務邏輯分離。

最後最重要的是你在相關的地方做檢查。如果你不知道這些相關的地方是什麼,那麼你需要回到應用程序的繪圖板來確定所有入口點。這些入口點是您想要應用細粒度授權/ cancan的位置。

查看XACML reference architecture瞭解正式架構概述。