【问题标题】:Declarative Authorization (permissions) for Backbone Views主干视图的声明式授权(权限)
【发布时间】:2013-01-31 18:24:04
【问题描述】:

前言: 任何来自 Rails 社区的人都可能熟悉在服务器端声明模型操作授权的 cancan。 IE。可以吗?(:read, Project)

背景:但是,在前端的 UI 层中,我还没有找到任何提供相同类型的抽象来处理用户看到的内容和他们有权做的事情(显然总是有一个后端身份验证层) .例如,您是否向用户显示按钮?我们是否包含“contenteditable”元素属性?如果用户点击“喜欢”,我们会尝试注册还是向他们显示登录对话框?

问题:有人知道处理此类 UI 问题的框架/工具/库/最佳实践吗?

跟进:问题是在视图中还是在模板中进行评估?这是模板语言的特性还是我们传入模板的一组布尔变量?

除此之外: 我有一个 cancan 模仿工具的想法,其中方法签名类似于 App.can('like',project,user),其中 project 和 user 是 BB 模型对象。但问题可能是用户可能能够对任何给定对象执行的不同操作的数量。 IE。喜欢项目、编辑项目、评论项目、邀请朋友加入项目等。其中一些可以简化为 RESTful 操作,但我认为大多数人会同意 UI 呈现更多类型的操作。

【问题讨论】:

  • 我不知道有什么专门做这个的框架,但一个简单的解决方案是让你的“can”对象成为一个 Backbone.Model,然后将该模型传递给你的视图(这可以用它来检查“我应该渲染 foo 吗?”)。

标签: javascript templates backbone.js cancan declarative


【解决方案1】:

我们在项目中遇到了同样的情况,页面中的所有内容都应该根据授予用户的权限显示和隐藏,这是我想出的解决方案。

您需要先在用户中保存权限并在客户端加载它们;然后您可以按如下方式检查它们

1-在你的基础视图中声明“filterByPermission”函数(你所有的视图都应该继承这个)

class SampleProject.Views.BaseView extends Backbone.View

  filterByPermission:=>
    #these views will be removed incase user does not have a specific permission
    if @views_permissions?
      for permission, selector of @views_permissions
        unless SampleProject.current_user.has_permission permission
          @$(selector).remove()

    #these views will be removed incase user has a specific permission
    if @remove_views_permissions?
      for permission, selector of @remove_views_permissions
        if SampleProject.current_user.has_permission permission
          @$(selector).remove()

2-然后您可以进入另一个继承基本视图的视图并在“views_permissions”中定义您的权限(类似于事件哈希)

class SampleProject.Views.UsersIndex extends SampleProject.Views.BaseView
  views_permissions:
    "create_users":  "#js_create_user_li, #new_user_modal"
    "import_users": "#js_import_btn_li, #import_form_li"
    "edit_users"  :  "#edit_user_modal"
    "delete_users"  :  "#js_delete_user_li, .js-user-selector-header"

  render:=>
    #render your view here
    @filterByPermission()

3-在渲染视图后调用@filterByPermission()。

这样您就可以在一个地方根据权限控制视图,而无需在整个代码中添加 if 语句

【讨论】:

    【解决方案2】:

    不确定到底有哪些框架,但您可以让 Rails 或您使用的任何服务器端框架将您的权限呈现为 JavaScript 对象。

    例如:

    var userAuth = { userId: 1234, userType: 'Admin',
                     /** A little more complex permission scenario */
                     privileges: [{ProjectA: 'admin'}, 
                                  {ProjectB: 'user'}, 
                                  {ProjectC: 'noaccess'}]};
    

    因此在您的视图或模板中,您可以根据当前登录用户的权限以声明方式呈现一段 UI 元素。例如,使用 Underscore 模板,您可以执行一些 JavaScript 逻辑和检查。

    /** Operate using a declared variable */
    <% if (userAuth.userType === 'Admin') {%>
        <div>This is only shown to admin.</div>
    <% } %>
    
    /** OR operate on the actual property on the working model */
    <% if (myModelProperty === 'Admin') {%>
        <div>This is only shown to admin.</div>
    <% } %>
    

    这种类型的检查也可以在实际的View本身中进行,以根据用户等限制某些功能。

    【讨论】:

    • 感谢您的回答。的确,我可以做到这一点,但问题是当这些权限比管理员与非管理员复杂得多时。此外,有时权限取决于复杂的关系,例如,如果您是具有管理员权限的项目的成员,您可以编辑对该项目的评论。
    • 我明白你在说什么。您还可以执行另一个 AJAX 请求来执行其他检查并让服务器端检查权限。您还可以根据权限的复杂程度执行以下操作:var userAuth = {userId: 1234, privileges: [{ProjectA: 'admin'}, {ProjectB: 'user'}, {ProjectC: 'noaccess'}]};
    • 是的,AJAX 请求是另一种选择,但需要在速度上进行权衡。此外,通常客户已经有足够的信息来回答权限问题,但没有有组织的方式来提出问题。当然,所有授权都是在服务器端强制执行的,但最好有一个可以自己执行此操作的 UI。就像软验证:github.com/n-time/backbone.validations 客户端和服务器端强验证很好地结合在一起。
    • 如果你缓存了这些权限,那么在做 AJAX 的时候速度应该是非常低的。您还可以提前将这些权限存储在 cookie 中。
    • 如何转储权限以缓存/存储它们?我知道这是 cantango 的一个功能,但我没有使用它...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 2014-04-25
    相关资源
    最近更新 更多