Zoeken…


Invoering

CanCan is een eenvoudige autorisatiestrategie voor Rails die is losgekoppeld van gebruikersrollen. Alle machtigingen worden op één locatie opgeslagen.

Opmerkingen

Vergeet voor het gebruik van CanCan niet om Gebruikers aan te maken, hetzij door een juweel te bedenken of handmatig. Maak een Admin-gebruiker aan voor maximale functionaliteit van CanCan.

Aan de slag met CanCan

CanCan is een populaire autorisatiebibliotheek voor Ruby on Rails die de gebruikerstoegang tot specifieke bronnen beperkt. Het nieuwste juweeltje (CanCanCan) is een voortzetting van het dode project CanCan .

Machtigingen worden gedefinieerd in de klasse Ability en kunnen worden gebruikt vanuit controllers, views, helpers of elke andere plaats in de code.

Om autorisatie-ondersteuning aan een app toe te voegen, voegt u de CanCanCan-edelsteen toe aan de Gemfile :

gem 'cancancan'

Definieer vervolgens de vaardigheidsklasse:

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

  def initialize(user)
  end
end

Controleer vervolgens de autorisatie met load_and_authorize_resource om geautoriseerde modellen in de controller te laden:

class ArticlesController < ApplicationController
  load_and_authorize_resource

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

authorize! om autorisatie te controleren of een uitzondering te maken

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

can? om te controleren of een object is geautoriseerd tegen een bepaalde actie ergens in de controllers, views of helpers

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

Opmerking: hierbij wordt ervan uitgegaan dat de ondertekende gebruiker wordt geleverd door de methode current_user .

Vaardigheden definiëren

Vaardigheden worden in de klasse Ability gedefinieerd met behulp van can en cannot methoden. Overweeg het volgende voorbeeld met commentaar voor basisreferentie:

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

Omgaan met een groot aantal vaardigheden

Zodra het aantal definities van vaardigheden begint te groeien, wordt het steeds moeilijker om met het bestand Ability te werken.

De eerste strategie om deze kwestie aan te pakken, is om vaardigheden te verplaatsen naar zinvolle methoden, zoals in dit voorbeeld:

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

Zodra deze klasse groot genoeg is geworden, kun je proberen deze in verschillende klassen op te splitsen om de verschillende verantwoordelijkheden als volgt te verwerken:

# 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

en definieer die klassen dan als:

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

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

en ga zo maar door met Abilities::Authenticated , Abilities::Admin of een ander.

Test snel een vaardigheid

Als je snel wilt testen of een vaardigheidsklasse de juiste machtigingen geeft, kun je een vaardigheid in de console of in een andere context initialiseren terwijl de railsomgeving is geladen, geef je een gebruikersinstantie door om te testen tegen:

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

Meer informatie: https://github.com/ryanb/cancan/wiki/Testing-Abilities



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow