Ruby on Rails
Auktorisation med CanCan
Sök…
Introduktion
CanCan är en enkel auktoriseringsstrategi för Rails som är frikopplad från användarroller. Alla behörigheter lagras på en enda plats.
Anmärkningar
Innan du använder CanCan, glöm inte att skapa användare antingen genom att utforma pärla eller manuellt. Skapa en Admin-användare för att få maximal funktion av CanCan.
Komma igång med CanCan
CanCan är ett populärt auktoriseringsbibliotek för Ruby on Rails som begränsar användarnas åtkomst till specifika resurser. Den senaste pärlan (CanCanCan) är en fortsättning på det döda projektet CanCan .
Behörigheter definieras i Ability
och kan användas från kontrollörer, vyer, hjälpare eller någon annan plats i koden.
Lägg till CanCanCan-pärla i Gemfile
att lägga till auktoriseringsstöd till en app:
gem 'cancancan'
Definiera sedan förmåga klass:
# app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
end
end
Kontrollera sedan behörigheten med hjälp av load_and_authorize_resource
att ladda godkända modeller i regulatorn:
class ArticlesController < ApplicationController
load_and_authorize_resource
def show
# @article is already loaded and authorized
end
end
authorize!
för att kontrollera godkännande eller göra ett undantag
def show
@article = Article.find(params[:id])
authorize! :read, @article
end
can?
för att kontrollera om ett objekt är auktoriserat mot en viss åtgärd var som helst i kontrollerna, vyerna eller hjälparna
<% if can? :update, @article %>
<%= link_to "Edit", edit_article_path(@article) %>
<% end %>
Obs: Detta förutsätter att den signerade användaren tillhandahålls med den current_user
.
Definiera förmågor
Förmågor definieras i Ability
hjälp av can
och cannot
metoder. Tänk på följande kommenterade exempel för grundläggande referens:
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
Hantera ett stort antal förmågor
När antalet definitioner av förmågor börjar växa i antal blir det allt svårare att hantera Ability-filen.
Den första strategin för att hantera denna fråga är att flytta förmågor till meningsfulla metoder enligt detta exempel:
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
När denna klass har blivit tillräckligt stor kan du försöka dela upp den i olika klasser för att hantera de olika ansvarsområdena som detta:
# 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
och definiera sedan dessa klasser som:
# app/models/abilities/guest.rb
module Abilities
class Guest
include CanCan::Ability
def initialize(user)
# Abilities for anonymous visitors only
end
end
end
och så vidare med Abilities::Authenticated
, Abilities::Admin
eller annat.
Testa snabbt en förmåga
Om du snabbt vill testa om en kapacitetsklass ger rätt rättigheter kan du initiera en kapacitet i konsolen eller i ett annat sammanhang med skenmiljön laddad, bara skicka en användarinstans att testa mot:
test_ability = Ability.new(User.first)
test_ability.can?(:show, Post) #=> true
other_ability = Ability.new(RestrictedUser.first)
other_ability.cannot?(:show, Post) #=> true
Mer information: https://github.com/ryanb/cancan/wiki/Testing-Abilities