权限控制[1] CanCan + Rolify + Devise

用Gem进行安装

Reference:

说明

  • 使用devise、cancan和rolify组件建立用户权限模型的说明。
    devise:负责用户注册、登录、退出、找回密码等操作。 devise_github

  • cancan:负责角色建立、对角色授权、在页面中根据授权是否显示元素,以及模型中超出授权时抛出异常。 cancan

  • rolify:负责将用户与角色关联。rolify_github
    在Gemfile中添加如下信息

1. 安装devise, rolify, cancan
[Gemfile]
gem 'devise' 
gem "rolify" 
gem 'cancan' 

然后在命令行中,用 $bundle install 进行安装。

2. Devise - install

$ rails generate devise:install

并按照提示,进行相关配置

esxi23v113@esxi23v113:~/Aptana Studio Workspace/blog$ rails generate devise:install
Running via Spring preloader in process 15821
      create  config/initializers/devise.rb




create config/locales/devise.en.yml =============================================================================== Some setup you must do manually if you haven't yet: 1. Ensure you have defined default url options in your environments files. Here is an example of default_url_options appropriate for a development environment in config/environments/development.rb: config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } In production, :host should be set to the actual host of your application. 2. Ensure you have defined root_url to *something* in your config/routes.rb. For example: root to: "home#index" 3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example: <p class="notice"> rails g devise:views ===============================================================================
3.Devise - generate user
$ rails generate devise User
4.CanCan - generate ability
esxi23v113@esxi23v113:~/Aptana Studio Workspace/blog$ rails g cancan:ability
Running via Spring preloader in process 15759
      create  app/models/ability.rb
5.Rolify - generate role
esxi23v113@esxi23v113:~/Aptana Studio Workspace/blog$ rails g rolify Role User
Running via Spring preloader in process 16236
      invoke  active_record
      create    app/models/role.rb
      invoke    test_unit
      create      test/models/role_test.rb
      create      test/fixtures/roles.yml
      insert    app/models/role.rb
      create    db/migrate/20170719024020_rolify_create_roles.rb
      insert  app/models/user.rb




create config/initializers/rolify.rb =============================================================================== An initializer file has been created here: config/initializers/rolify.rb, you can change rolify settings to match your needs. Defaults values are commented out. A Role class has been created in app/models (with the name you gave as argument otherwise the default is role.rb), you can add your own business logic inside. Inside your User class (or the name you gave as argument otherwise the default is user.rb), rolify method has been inserted to provide rolify methods.
6.Run db:migrate
esxi23v113@esxi23v113:~/Aptana Studio Workspace/blog$ rake db:migrate
== 20170719023958 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0380s
== 20170719023958 CreateUsers: migrated (0.0382s) =============================
== 20170719024020 RolifyCreateRoles: migrating ================================
-- create_table(:roles, {})
   -> 0.0046s
-- create_table(:users_roles, {:id=>false})
   -> 0.0129s
-- add_index(:roles, :name)
   -> 0.0199s
-- add_index(:roles, [:name, :resource_type, :resource_id])
   -> 0.0046s
-- add_index(:users_roles, [:user_id, :role_id])
   -> 0.0041s
== 20170719024020 RolifyCreateRoles: migrated (0.0467s) =======================
7.Custom Devise controller/View

Devise会帮你生成注册/登录一系列的功能,你可以定制自己想要的,只需要覆盖对应的文件or方法即可。具体参考官方文档。此处举例利用命令生成controller。

esxi23v113@esxi23v113:~/Aptana Studio Workspace/shop$ rails generate devise:controllers users
Running via Spring preloader in process 31906
      create  app/controllers/users/confirmations_controller.rb
      create  app/controllers/users/passwords_controller.rb
      create  app/controllers/users/registrations_controller.rb
      create  app/controllers/users/sessions_controller.rb
      create  app/controllers/users/unlocks_controller.rb




create app/controllers/users/omniauth_callbacks_controller.rb =============================================================================== Some setup you must do manually if you haven't yet: Ensure you have overridden routes for generated controllers in your routes.rb. For example: Rails.application.routes.draw do devise_for :users, controllers: { sessions: 'users/sessions' } end ===============================================================================
8.Select devise function module.

Devise 功能模块:

  1. Encryptable:除了内置的Bcrypt(默认),增加支持认证机制
  2. Lockable:锁定一定数量的失败尝试登录。通过电子邮件或之后才能解锁
  3. validatable:有效性:提供的电子邮件及密码鉴定。它是可选的,可定制的,所以你可以定义自己的代码。
  4. Timeoutable:在一特定时期(expires sessions)没有活动。
  5. Trackable(跟踪):追踪 登录的次数、时间戳记签字和IP地址。
  6. Rememberable(记忆):管理产生和清除表示来自用户保存的cookie的标记(token)
  7. Registerable(注册):处理用户注册过程,也可以让他们编辑和摧毁他们的帐户。
  8. recoverable(重设)重置用户密码并且发送重置指令。
  9. Confirmable 注册登录认证
  10. Omniauthable: adds Omniauth (github.com/intridea/omniauth) support;
  11. Database Authenticatable:登录时加密密码并在数据库中验证用户真实性。 (可以通过POST请求或HTTP基本认证)
  12. Token Authenticatable: 基于token的用户登录(also known as “single access token”)。token可以通过查询字符串或HTTP基本身份认证。

查看User.rb

你会看到device添加的模块,选择你需要的即可。

class User 
9.Use sign_in / sign_out

本功能只针对本系统,本系统自己做了登录验证,验证通过后,我们可以直接用sign_in(@user)方法把当前的user添加到session中,之后我们就可以用current_user查看当前登陆的用户。

具体可参考官方API:Method: Devise::Controllers::SignInOut#sign_in


# sign_in(resource_or_scope, *args) ⇒ Object

Sign in a user that already was authenticated. This helper is useful for logging users in after sign up. All options given to sign_in is passed forward to the set_user method in warden.

Examples:

sign_in :user, @user                      # sign_in(scope, resource)
sign_in @user                             # sign_in(resource)
sign_in @user, event: :authentication     # sign_in(resource, options)
sign_in @user, store: false               # sign_in(resource, options)
10.Access Control (use rolify)

add_role :admin # 用来添加角色

has_role? :admin #用来判断是否有这个角色

def create
    admin = Admin.new(admin_params)
    if admin.save
      admin.add_role params[:role]
      respond_to do |format|
        format.html
        format.js
      end
    else
      render 'new'
    end
  end
11.Set access in ability.rb
  • :manage: 是指這個 controller 內所有的 action
  • :read : 指 :index 和 :show
  • :update: 指 :edit 和 :update
  • :destroy: 指 :destroy
  • :create: 指 :new 和 :crate
  • :all 是指所有 object (resource)
  • 其他非RESTful的method (如:search)也可以列上去,但是要逐条列出来
  • 组合 : alias_action
     
    alias_action :update, :destroy, :to => :modify
    can :modify, Comment
class Ability
  include CanCan::Ability
  def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
    #   user ||= User.new # guest user (not logged in)
    #   if user.admin?
    #     can :manage, :all
    #   else
    #     can :read, :all
    #   end
    #
    # The first argument to `can` is the action you are giving the user
    # permission to do.
    # If you pass :manage it will apply to every action. Other common actions
    # here are :read, :create, :update and :destroy.
    #
    # The second argument is the resource the user can perform the action on.
    # If you pass :all it will apply to every resource. Otherwise pass a Ruby
    # class of the resource.
    #
    # The third argument is an optional hash of conditions to further filter the
    # objects.
    # For example, here the user can only update published articles.
    #
    #   can :update, Article, :published => true
    #
    # See the wiki for details:
    # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
    user ||= User.new
    if user.has_role? :admin
      can :manage, :all
    elsif user.has_role? :Manager
      can :read, Production
      can :update, Production 
    else
      can :read, Production
    end
  end
end
12.Access control in controller

Reference: github: authorizing-controller-actions

load_and_authorize_resource method in your controller to load the resource into an instance variable and authorize it automatically for every action in that controller

class ProductsController 
13.Access control in view
<table>
  <tbody>
    <% @productions.each do |production| %>
      <tr>
        <td><%= production.name %></td>
        <td><%= production.price %></td>
        <td><%= production.amount %></td>
        <% if can? :read,Production%>
        <td><%= link_to 'Show', production %></td>
        <% end %>
        <% if can? :update,Production%>
        <td><%= link_to 'Edit', edit_production_path(production) %></td>
        <% end %>
        <% if can? :destroy,Production%>
        <td><%= link_to 'Destroy', production, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        <% end%>
      </tr>
    <% end %>
  </tbody>
</table>
<% if can? :create,Production%>
<%= link_to 'New Production', new_production_path %>
<% end %>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值