Pundit je Ruby dragulj koji obrađuje autorizaciju putem vrlo jednostavnog API-ja.
Imajte na umu da se autorizacija razlikuje od autentifikacije - autentifikacija potvrđuje da ste ono što kažete da jeste, a autorizacija potvrđuje da imate dozvolu za izvođenje radnje.
Pundit je potpuno u autorizacijskom kampu - koristite drugi sustav provjere autentičnosti poput Devise za obradu autentičnosti.
Kako radite s Punditom
Korak 1: Možete stvoriti Policy
klasu koja se bavi autorizacije pristupa određenoj vrsti rekord - da li to biti Blog
ili Potato
ili User
.
Korak 2: Pozovite ugrađenu authorize
funkciju, prosljeđujući ono za što pokušavate autorizirati pristup.
Korak 3: Pundit će pronaći odgovarajuću Policy
klasu i pozvati Policy
metodu koja odgovara nazivu metode koju autorizirate. Ako se vrati istina, imate dozvolu za izvođenje radnje. Ako ne, izbacit će iznimku.
Prilično je jednostavno. Logika za određene modele ugrađena je u vlastitu klasu politike, što je izvrsno za održavanje urednosti. Konkurentska autorizacijska knjižnica cancancan imala je problema s kompliciranim dozvolama koje su izmakle kontroli.
Potrebne su manje dorade
Punditove jednostavne konvencije ponekad treba doraditi kako bi podržale složenije slučajeve korištenja autorizacije.
Pristupite više informacija iz politike
Pundit prema zadanim postavkama pruža dva objekta vašem kontekstu autorizacije: User
i Record
koji je autoriziran. To je dovoljno ako imate sistemske uloge u vašem sustavu poput Admin
ili Moderator
, ali nije dovoljno kada trebate autorizirati specifičniji kontekst.
Recimo da ste imali sustav koji je podržavao koncept Organization
i morali ste podržavati različite uloge unutar tih organizacija. Ovlaštenje za čitav sustav neće ga smanjiti - ne želite da administrator Organizacijskog krumpira može raditi stvari s Orange Orangeom ako nije administrator obje organizacije. Kada odobravate ovaj slučaj, trebat će vam pristup 3 stavke: podacima User
o Record
, i ulozi korisnika u Organization
. Idealan bi slučaj bio imati pristup organizaciji kojoj zapis pripada, ali učinimo to težim i recimo da mu nemamo pristup putem zapisa ili korisnika.
Pundit pruža priliku da pruži dodatni kontekst. Definiranjem funkcije koja se zove pundit_user
, to vam omogućuje da promijenite ono što se smatra a user
. Ako iz te funkcije vratite objekt s autorizacijskim kontekstom, taj će kontekst biti dostupan vašim pravilima.
application_controller.rb
class ApplicationController < ActionController::Base include Pundit
def pundit_user AuthorizationContext.new(current_user, current_organization) endend
authorization_context.rb
class AuthorizationContext attr_reader :user, :organization
def initialize(user, organization) @user = user @organization = organization endend
application_policy.rb
class ApplicationPolicy attr_reader :request_organization, :user, :record
def initialize(authorization_context, record) @user = authorization_context.user @organization = authorization_context.organization @record = record end
def index? # Your policy has access to @user, @organization, and @record. endend
Vaša bi pravila sada imala pristup svim trima vrstama podataka - trebali biste biti u mogućnosti vidjeti kako biste pristupili više informacija ako vam zatrebaju.
Zamijenite konvenciju i navedite koju politiku koristiti
Pundit koristi konvencije imenovanja kako bi podudarao ono što pokušavate autorizirati s pravim pravilima. Većinu vremena ovo dobro funkcionira, ali u određenim slučajevima možda ćete trebati nadjačati ovu konvenciju, na primjer kada želite autorizirati opću radnju nadzorne ploče koja nema pridruženi model. Možete predati simbole da odredite koju radnju ili politiku koristiti za autorizaciju:
#Below will call DashboardPolicy#bake_potato?authorize(:dashboard, :bake_potato?)
Ako imate model koji je drugačije imenovan, također možete nadjačati policy_class
funkciju unutar samog modela:
class DashboardForAdmins def self.policy_class DashboardPolicy # This forces Pundit to use Dashboard Policy instead of looking # for DashboardForAdminsPolicy endend
Testiranje
Odobrenje je jedna od stvari koje toplo preporučujem uz automatsko testiranje. Pogrešno ih postavljanje može biti katastrofalno, a po mom mišljenju jedna je od najmoćnijih stvari za ručno testiranje. Sposobnost pokretanja jedne naredbe i saznanja da niste nehotice promijenili nijedno poslovno pravilo za autorizaciju je sjajan osjećaj.
Pundit autorizaciju testiranja čini vrlo jednostavnom.
def test_user_cant_destroy? assert_raises Pundit::NotAuthorizedError do authorize @record, :destroy? endend
def test_user_can_show? authorize @record, :show?end
Sve u svemu volim Pundit. Koristim ga samo kratko vrijeme, ali već mi je draži od cancancana - jednostavno se čini održivijim i provjerljivijim.
Je li vam ova priča bila korisna? Molimo pljeskajte da pokažete svoju podršku!
Ako vam nije bilo korisno, javite mi zašto s komentarom !