Come posso implementare i privilegi del forum

Ho iniziato a sviluppare un'applicazione per forum in PHP sul mio MVC Framework e sono arrivato allo stadio in cui assegno le autorizzazioni ai membri (ad esempio: READ, WRITE, UPDATE, DELETE).

Ora, so che posso aggiungere 5 colonne sotto la tabella utente nel mio database e impostarle su 1 | 0, ma questo mi sembra troppo se voglio aggiungere altre regole, ad esempio MOVE.

E come posso assegnare questi privilegi dynamicmente agli utenti singolarmente?

Ho sentito di usare una maschera di bit, ma sarebbe davvero bello se potessi capirli appieno prima di continuare.

Hai un esempio di come potrei implementarlo?

Il metodo che hai descritto – privilegi individuali memorizzati in colonne – è semplice a scapito della flessibilità (come hai notato).

Il metodo di Zuul è ancora più semplice ed essenzialmente uguale al tuo, tranne che evita la necessità di qualsiasi istruzione "ALTER TABLE". Tuttavia, non è normalizzato, non è facilmente interrogabile e non è autocostruito.

Un altro problema con entrambi questi methods è che man mano che la vostra base di utenti cresce, trovenetworking sempre più di un dolore mantenere i privilegi di tutti impostati correttamente. Ti troverai con molti utenti che hanno bisogno esattamente degli stessi privilegi. Tuttavia, al fine di modificare i privilegi di un utente, ad esempio per accogliere un nuovo privilegio, è necessario entrare e aggiungere tale privilegio a ciascun utente che ne ha bisogno individualmente. Major PITA.

Per un forum, è improbabile che sia necessaria la gestione dei privilegi per utente. È più probabile che alcune classi di utenti come gli utenti anonimi, gli utenti registrati, i moderatori, gli amministratori, ecc. Lo renderebbero idoneo per il controllo degli accessi basato sui ruoli (RBAC). In questo sistema assegneresti ciascun utente a un ruolo e concedere i privilegi al ruolo. I privilegi verrebbero archiviati come righe in una tabella "privilegio". quindi lo schema del database semplificato sarà simile a:

PRIVILEGE int id (primary key) varchar description ROLE_PRIVILEGE_JOIN privilege_id (foreign key) role_id (foreign key) ROLE int id (primary key) varchar description USER int id (primary key) int role_id (foreign key) 

Questo model è utilizzato in molte applicazioni che trattano i privilegi dell'utente. Aggiungi tutti i privilegi che chiunque potrebbe avere come fila nella tabella dei privilegi; aggiungere each ruolo che qualsiasi utente possa avere nella tabella dei ruoli; e collegarli in modo appropriato nella tabella role_privilege_join.

L'unico vero svantaggio è che poiché viene utilizzata una tabella di join, la query "can user X do Y" sarà un po 'più lenta.

Una bitmask di permessi è meglio compresa quando rappresentata come binaria, con each cifra che rappresenta un permesso attivo o disattivo. Quindi, se esistono le autorizzazioni X, Y e Z, e ho solo accesso a X e Z, 101 rappresenterebbe che ho il primo e il terzo permesso a me concessi, ma non il secondo. Il numero binario 101 è equivalente al numero decimale 5 , quindi è quello che verrebbe archiviato nel database. Un singolo, piccolo numero integer è un object molto più efficiente da memorizzare rispetto a una string o più interi piccoli.

EDIT: mi sono reso conto di quanto fosse facile sfruttare le funzioni di conversione esistenti per get un'implementazione piuttosto rapida. Ecco un esempio.

 <?php function bitmask_expand($n) { // 9 returns arrays(1, 0, 0, 1) return str_split(base_convert($n, 10, 2)); } function bitmask_compact($a) { // arrays(1, 0, 0, 1) returns 9 return (int) base_convert(implode($a), 2, 10); } $ns = range(0, 7); foreach($ns as $n) { print_r($b = bitmask_expand($n)); echo bitmask_compact($b), "\n\n"; } 

È ansible get performance migliori se si utilizzano loop, anziché tornare indietro e da stringhe, ma ciò illustra il principio in modo abbastanza chiaro.

Vorrei creare una tabella chiamata "ruoli":

 CREATE TABLE Roles( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id), rolename VARCHAR(30)) 

Mantieni le autorizzazioni che desideri. Quindi creare una tabella chiamata "UserRoles" per colbind gli utenti ai ruoli:

 CREATE TABLE UserRoles( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id), UserId INT, RoleID INT) 

Un sacco di flessibilità e facile da build (ad es. Flusso di lavoro, regole, ecc.) (Aggiungerei anche chiavi esterne)

Non è necessario complicarlo, basta usare un field "ex: permessi" e fare qualcosa del tipo:

$ permissions = "1; 1; 0; 1";

where nella tua preoccupazione si legge:

LEGGI – 1 (ansible)

WRITE – 1 (can)

AGGIORNAMENTO – 0 (imansible)

CANCELLA – 1 (ansible)

poi, quando controlli, usa "esplode" per ";" …

In questo modo, puoi sempre applicare più tipi di permessi senza cambiare tabella … quindi riduci la tabella e la query più velocemente!

È una soluzione per il tuo problema 🙂