使用Angular JS客户端的Rails REST API权限(CanCan).如何根据权限呈现UI?

Pav*_*nko 10 javascript ruby rest ruby-on-rails angularjs

我正在构建一个只能通过JSON API(Rails 4.0,PostgreSQL)工作的项目.这是一个基于数据库的权限的大应用程序.我有AngularJS应用程序,可以使用这个REST API.

简化结构:

employees >--- position ---< permission
Run Code Online (Sandbox Code Playgroud)

Employee.rb

belongs_to :position
Run Code Online (Sandbox Code Playgroud)

Position.rb

has_many :employees
has_many :permissions, dependent: :destroy
Run Code Online (Sandbox Code Playgroud)

Permission.rb

belongs_to :position
## Columns
 # action (:manage, :read, :update, :create, etc...)
 # subject_class
 # subject
Run Code Online (Sandbox Code Playgroud)

我对AngularJS客户端的操作按钮/链接有问题.

例如,我不想在Angular应用程序中的某处显示链接"Add Order",因为Employee的位置权限只允许读取资源而不是修改它:

id    action     subject_class     subject
 1    :read      Order            
Run Code Online (Sandbox Code Playgroud)

我是怎么试图解决这个问题的

我创建了一个资源GET api/v1/employees/me,它返回current_employee及其所有权限:

"employee": {
    ...
    :position": {
        ...
        "permissions": {
           {"id": 1, "action": "read", "subject_class": "Order", "subject": ""},
           {"id": 6, "action": "manage", "subject_class": "Waybill", "subject": ""}
        }
     }
  }
Run Code Online (Sandbox Code Playgroud)

所以我在客户端拥有所有权限,但是使用AngularJS应用程序UI获得权限的最佳方式是什么?

use*_*102 7

经过一番挖掘后,我想我找到了一个可行的解决方案.这是您的方法与Jon Samwell上述评论的结合:

http://jonsamwell.com/url-route-authorization-and-security-in-angular/

和Eric Zou的博客文章:

http://blog.ericzou.com/2013/05/03/using-angularjs-for-existing-rails-app/

总结一下:

  • 创建一个rails服务,abilities以json格式响应当前用户在导轨端的cancan .看起来这就是您开始使用GET权限请求.这样(来自Eric的博客)为当前用户调用/abilities.json时:
{
  "manage": {
    "User": true,
    "Post": false,
    ...
  },
  "read": {
    "User": true,
    "Post": true
    ...
  },
  "Update": {
    "User": true,
    "Post": false
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

要获得特定用户的能力,您可以Ability.new(current_user)在控制器中执行某些操作.它返回一个带有一堆规则的对象.规则具有允许您限制对特定帖子的访问的条件.

  • 以角度形式创建一个处理解析的服务,它可以作为从rails端获得的内容之间的抽象层(确定您是否可以访问路由或者可以管理,读取等特定模型)(例如,可以吗?(:管理,发布) )).您可以根据需要使这项服务变得复杂.

  • 还可以在angular中创建一个指令来处理要显示的内容.Eric建议使用ng-show来做这件事,这很好,但用类似于Jon的建议清理它:<div access="post" access-type="read" access-options="options">Secret Post</div>对我有意义.

确保您没有从服务器上提供任何您不希望用户在攻击您的javascript以更改其权限后看到的内容.这不是安全性,而是UI管理.