de Joseph Gefroh

Pundit este o bijuterie Ruby care gestionează autorizarea printr-un API foarte simplu.

Amintiți-vă că autorizarea este diferită de autentificare – autentificarea înseamnă verificarea faptului că sunteți cine spuneți că sunteți, iar autorizarea verifică dacă aveți permisiunea de a efectua o acțiune.

Pundit se află direct în tabăra de autorizare – utilizați un alt sistem de autentificare, cum ar fi Înțelegeți pentru a gestiona autentificarea.

Cum lucrezi cu Pundit

Pasul 1: Creați un Policy clasă care se ocupă cu autorizarea accesului la un anumit tip de înregistrare – fie că este vorba de un Blog sau Potato sau User.

Pasul 2: Numiți încorporat authorize funcție, trecând la ceea ce încercați să autorizați accesul.

Pasul 3: Pundit va găsi ceea ce este potrivit Policy clasa și sunați la Policy metoda care se potrivește cu numele metodei pe care o autorizați. Dacă revine la adevărat, aveți permisiunea de a efectua acțiunea. Dacă nu, va arunca o excepție.

Este destul de simplu. Logica pentru modele specifice este încapsulată în propria sa clasă de politici, ceea ce este excelent pentru a menține lucrurile ordonate. Biblioteca de autorizare concurentă cancancan a avut probleme cu permisiunile complicate care scăpau de sub control.

Sunt necesare modificări minore

Convențiile simple ale lui Pundit trebuie uneori modificate pentru a susține cazuri de utilizare a autorizațiilor mai complexe.

Accesați mai multe informații din cadrul unei politici

În mod implicit, Pundit oferă două obiecte contextului dvs. de autorizare: User si Record fiind autorizat. Acest lucru este suficient dacă aveți roluri la nivel de sistem în sistemul dvs., cum ar fi Admin sau Moderator, dar nu este suficient atunci când aveți nevoie de autorizare într-un context mai specific.

Să presupunem că ați avut un sistem care susținea conceptul de Organizationși a trebuit să sprijiniți diferite roluri în cadrul acelor organizații. Autorizarea la nivel de sistem nu o va întrerupe – nu doriți ca un administrator al Organizației de cartofi să poată face lucruri la Organizația Orange, cu excepția cazului în care sunt administratori ai ambelor organizații. Când autorizați acest caz, veți avea nevoie de acces la 3 elemente: User, Record, precum și informațiile despre rolul utilizatorului în Organization. Cazul ideal ar fi să avem acces la organizația căreia îi aparține înregistrarea, dar hai să o facem mai dificilă și să spunem că nu avem acces la aceasta prin intermediul înregistrării sau al utilizatorului.

Pundit oferă o oportunitate de a oferi un context suplimentar. Prin definirea unei funcții numită pundit_user, acest lucru vă permite să schimbați ceea ce este considerat a user. Dacă returnați un obiect cu contextul de autorizare din acea funcție, acel context va fi disponibil politicilor dvs.

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

Politicile dvs. ar avea acum acces la toate cele trei tipuri de informații – ar trebui să puteți vedea cum ați accesa mai multe informații dacă ați avea nevoie de ele.

Înlocuiți convenția și specificați ce politică să utilizați

Pundit folosește convenții de denumire pentru a potrivi ceea ce încercați să autorizați cu politica corectă. De cele mai multe ori acest lucru funcționează bine, dar, în anumite cazuri, poate fi necesar să înlocuiți această convenție, cum ar fi atunci când doriți să autorizați o acțiune generală a tabloului de bord care nu are un model asociat. Puteți trece simboluri pentru a specifica acțiunea sau politica de utilizat pentru autorizare:

#Below will call DashboardPolicy#bake_potato?authorize(:dashboard, :bake_potato?)

Dacă aveți un model numit diferit, puteți, de asemenea, să înlocuiți policy_class funcționează în cadrul modelului în sine:

class DashboardForAdmins  def self.policy_class   DashboardPolicy     # This forces Pundit to use Dashboard Policy instead of looking    # for DashboardForAdminsPolicy  endend

Testarea

Autorizarea este unul dintre acele lucruri pe care le recomand cu tărie să aveți în jur o suită de testare automată. Configurarea lor incorectă poate fi catastrofală și, în opinia mea, este unul dintre cele mai obositoare lucruri de testat manual. A fi capabil să executați o singură comandă și să știți că nu ați modificat în mod accidental nicio regulă de autorizare a afacerii este un sentiment extraordinar.

Pundit face autorizația de testare foarte simplă.

def test_user_cant_destroy?  assert_raises Pundit::NotAuthorizedError do    authorize @record, :destroy?  endend
def test_user_can_show?  authorize @record, :show?end

Per total îmi place Pundit. L-am folosit doar pentru o perioadă scurtă de timp, dar îl prefer deja pe cel de cancancan – se simte mai ușor de întreținut și testabil.

Ați găsit utilă această poveste? Vă rog Bate să vă arăt sprijinul!
Dacă nu vi s-a părut util, vă rog să-mi spuneți de ce cu un cometariu!