Ruoli utente nel database [duplicato]

3

Quale sarebbe il modo più efficiente per memorizzare un ruolo degli utenti (nel mio caso) nel database?

Che aspetto ha la mia tabella utente:

id                         int(AI)
username                   varchar(80)
password                   varchar(255)

Ad esempio i diritti sarebbero come:

Ci dovrebbero essere i diritti per vedere una pagina:

  • Pagina1
  • Pagina2
  • Pagina 3
  • Pagina4

Quindi nel caso precedente dovresti avere il diritto di vedere Pagina1 e Pagina2 ma anche solo Pagina3

Puoi

  • Elimina post
  • Crea post
  • Modifica post

solo Pagina2

Tutte queste possibilità di combinazioni dovrebbero avere il loro ruolo.

Ora non so come memorizzarlo in una tabella.

Ho pensato di creare una tabella come questa:

role | page1 | page2 | page3 | page4 | page5 | page6 | delete | create | edit |
role1| yes   | yes   | no    | no    | no    | no    | yes    | yes    | yes  |

Ma penso che ci siano troppe combinazioni per usarlo, quindi ci deve essere un modo migliore / più efficiente / più facile per farlo.

Quindi la mia domanda è:

Qual è il modo migliore / più semplice per farlo?

    
posta Loko 16.02.2015 - 09:12
fonte

3 risposte

4

Devi definire le autorizzazioni per i ruoli, non per gli utenti. Agli utenti viene assegnato un ruolo che specifica il tipo di accesso che ha su una determinata pagina. Dai uno sguardo allo schema seguente:

I buoni esempi di ruoli potrebbero essere "manager", "admin", "user", "public". Il vantaggio di farlo in questo modo è che i ruoli sono facili da modificare in seguito. Se aggiungi una pagina e decidi che solo gli amministratori possono accedervi, cambiarla è semplice come cambiare il ruolo di amministratore e tutti gli utenti con quel ruolo prenderanno la modifica.

RolePermissions è il luogo in cui inserirai le autorizzazioni per le singole pagine. Dovrebbe avere un nome (che farai riferimento nel tuo programma come chiave, o direttamente dal nome della risorsa, anche se lo consiglierei per chiave), e una serie di permessi. È probabile che le autorizzazioni tipiche siano la vista, l'aggiornamento, la creazione e l'eliminazione, sebbene sia necessario creare almeno un paio di campi aggiuntivi per le autorizzazioni personalizzate che potrebbero essere specifiche per la pagina. View è un'abilitazione speciale che determinerà se l'utente può visualizzare o meno quella pagina e, in caso contrario, dovresti reindirizzare a una pagina di errore 401 oa una pagina di accesso.

C'è anche il problema di cosa fare se non riesci a trovare i permessi per una determinata pagina. Il mio pensiero è che si possa automaticamente presumere che l'utente non abbia le autorizzazioni per visualizzare quella pagina, tuttavia un approccio alternativo potrebbe essere quello di avere un ruolo speciale che non può (o non dovrebbe almeno) essere cancellato chiamato public. Se ti trovi nella circostanza che il ruolo di un utente non mostra esplicitamente le autorizzazioni, puoi fare automaticamente riferimento alle autorizzazioni di ruolo pubbliche per il comportamento corretto. In questo modo, in ultima analisi, devi solo specificare autorizzazioni che concedono più leniancy al ruolo di autorizzazione non pubblico piuttosto che dover sempre specificare autorizzazioni per ogni pagina e ruolo.

Le informazioni di accesso dovrebbero essere conservate nella tabella Utenti e dovrebbero essere separate dalle autorizzazioni. Anche come @Encaitar ha menzionato nella sua risposta, sarebbe saggio gestire gli hash delle password, e non le password stesse, crittografate o altrimenti.

    
risposta data 16.02.2015 - 16:12
fonte
1

"Buono", "facile" ed "efficiente" non sono solo tutti termini soggettivi e ambigui, molto spesso sono in conflitto tra loro . Scegliere una rappresentazione di dati è praticamente sempre un compromesso tra la bontà di un tipo e un altro tipo.

Avere campi separati per ogni diritto di lettura / scrittura / modifica per ogni pagina rende il layout di database più semplice: solo un mucchio di colonne. Ma è più difficile programmare, dal momento che qualunque codice controlli i diritti di modifica a pagina 1 deve essere duplicato per funzionare con pagina 2, pagina 3 ecc. Se avessi una struttura dati più intelligente, il codice sarebbe solo deve essere parametrizzato . Il codice duplicato è una fonte ben nota di difetti di coerenza: i processi di copia e incolla sono "semplici" da scrivere, ma in genere meno semplici da utilizzare successivamente. Se si prevede di dedicare più tempo alla manutenzione del programma piuttosto che scriverlo in primo luogo, è opportuno dare la priorità alla facilità di manutenzione. Ad esempio, una volta che viene inventata una quarta pagina, rifare il "taglia e incolla" di solito è una cosa difficile da correggere. Aumentare una costante che rappresenta un limite da 3 a 4 è banale.

Lo svantaggio di creare una rappresentazione strutturata dei dati (ad esempio una tabella di collegamento con colonne "numero di pagina", "ID utente" e "tipo di azione") richiede uno sforzo maggiore nella pianificazione e un po 'più di archiviazione dei dati nella produzione . Ci sono situazioni in cui questo costo è proibitivo (ad esempio se devi adattare il tuo programma in 4K byte), ma come ipotesi plausibile, presumo che tu non sia in quella situazione, quindi dovresti investire un piccolo sforzo in anticipo per migliorare la manutenzione e leggibilità del tuo codice.

    
risposta data 16.02.2015 - 09:21
fonte
1
  1. Non memorizzare password in un database, nemmeno password crittografate.
  2. Autenticazione e autorizzazione sono concetti diversi e, a meno che l'efficienza dello spazio non sia molto importante nel tuo database, dovresti prendere in considerazione la possibilità di suddividerli.
  3. Invece di avere una colonna per ogni tipo di permesso e quale oggetto si riferisce a te, dovresti dare un'occhiata alle autorizzazioni di codifica come fanno per le autorizzazioni * di file NIX.

Invece di memorizzare le password direttamente in un database, è possibile eseguire l'hash (una funzione che è matematicamente impossibile invertire) la password e memorizzare il risultato dell'hash nel database. Quindi, quando un utente tenta di accedere, eseguire lo stesso hash sulla password proposta e confrontarlo con quello memorizzato nel database, se corrispondono, l'utente ha inserito la password corretta. Ci sono una serie di problemi con questo; hai bisogno di una funzione di hash che non ha troppe possibilità di collisione (quando più di una password risolve lo stesso output), complessità della funzione di hash (la legge di Moore renderà più facile e più facile l'attacco di forza bruta), e lì sono "tavole arcobaleno" precalcolate che memorizzano le password / le coppie di hash di cui preoccuparsi (dovresti "salare" le password con una stringa pseudo-casuale in modo che siano diverse da quelle che l'attaccante si aspetta).

Se mantieni i nomi utente / password (o gli hash) e l'autorizzazione separata, manterrai le unità logiche separate e potrai dividerle in seguito se finisci per utilizzare qualcosa come LDAP.

* I permessi del file NIX usano ottale e aggiungono il numero insieme, quindi +4 per lettura, +2 per scrittura e +1 per esecuzione, per proprietario, gruppo e altro, quindi 751 verrebbe letto, scritto, eseguito per il proprietario, legge ed esegue per chiunque nel gruppo con autorizzazioni e solo eseguire le autorizzazioni per tutti gli altri.

    
risposta data 16.02.2015 - 09:43
fonte

Leggi altre domande sui tag