Buscar..


Introducción

CanCan es una estrategia de autorización simple para Rails que se desacopla de los roles de usuario. Todos los permisos se almacenan en una sola ubicación.

Observaciones

Antes de usar CanCan, no olvide crear Usuarios por gema o manualmente. Para obtener la máxima funcionalidad de CanCan puede crear un usuario administrador.

Empezando con CanCan

CanCan es una popular biblioteca de autorizaciones para Ruby on Rails que restringe el acceso de los usuarios a recursos específicos. La última gema (CanCanCan) es una continuación del proyecto muerto CanCan .

Los permisos se definen en la clase de Ability y se pueden usar desde controladores, vistas, ayudantes o cualquier otro lugar en el código.

Para agregar soporte de autorización a una aplicación, agregue la gema CanCanCan al Gemfile :

gem 'cancancan'

Luego define la clase de habilidad:

# app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
  end
end

Luego, verifique la autorización usando load_and_authorize_resource para cargar modelos autorizados en el controlador:

class ArticlesController < ApplicationController
  load_and_authorize_resource

  def show
    # @article is already loaded and authorized
  end
end

authorize! para comprobar la autorización o plantear una excepción

def show
  @article = Article.find(params[:id])
  authorize! :read, @article
end

can? para verificar si un objeto está autorizado contra una acción particular en cualquier lugar en los controladores, vistas o ayudantes

<% if can? :update, @article %>
  <%= link_to "Edit", edit_article_path(@article) %>
<% end %>

Nota: Esto supone que el usuario current_user es proporcionado por el método current_user .

Definiendo habilidades

Las habilidades se definen en la clase Ability utilizando los métodos de can y la cannot . Considere el siguiente ejemplo comentado para referencia básica:

class Ability
  include CanCan::Ability

  def initialize(user)
    # for any visitor or user
    can :read, Article

    if user
      if user.admin?
        # admins can do any action on any model or action
        can :manage, :all
      else
        # regular users can read all content
        can :read, :all
        # and edit, update and destroy their own user only
        can [:edit, :destroy], User, id: user_id
        # but cannot read hidden articles
        cannot :read, Article, hidden: true
      end
    else
      # only unlogged visitors can visit a sign_up page:
      can :read, :sign_up
    end
  end
end

Manejando gran cantidad de habilidades.

Una vez que el número de definiciones de habilidades comienza a crecer en número, se vuelve cada vez más difícil manejar el archivo de Habilidad.

La primera estrategia para manejar estos problemas es mover las habilidades a métodos significativos, según este ejemplo:

class Ability
  include CanCan::Ability

  def initialize(user)
    anyone_abilities 

    if user
      if user.admin?
        admin_abilities
      else
        authenticated_abilities
      end
    else
      guest_abilities
    end
  end

  private
  
  def anyone_abilities
    # define abilities for everyone, both logged users and visitors
  end

  def guest_abilities
    # define abilities for visitors only
  end

  def authenticated_abilities
    # define abilities for logged users only
  end

  def admin_abilities
    # define abilities for admins only
  end
end

Una vez que esta clase crezca lo suficiente, puede intentar dividirla en diferentes clases para manejar las diferentes responsabilidades de esta manera:

# app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    self.merge Abilities::Everyone.new(user)

    if user
      if user.admin?
        self.merge Abilities::Admin.new(user)
      else
        self.merge Abilities::Authenticated.new(user)
      end
    else
      self.merge Abilities::Guest.new(user)
    end
  end
end

y luego definir esas clases como:

# app/models/abilities/guest.rb
module Abilities
  class Guest
    include CanCan::Ability

    def initialize(user)
      # Abilities for anonymous visitors only
    end
  end
end

y así sucesivamente con Abilities::Authenticated , Abilities::Admin o cualquier otro.

Prueba rápidamente una habilidad

Si desea probar rápidamente si una clase de habilidad está dando los permisos correctos, puede inicializar una habilidad en la consola o en otro contexto con el entorno de rieles cargados, solo pase una instancia de usuario para probar:

test_ability = Ability.new(User.first)
test_ability.can?(:show, Post) #=> true
other_ability = Ability.new(RestrictedUser.first)
other_ability.cannot?(:show, Post) #=> true

Más información: https://github.com/ryanb/cancan/wiki/Testing-Abilities



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow