Come mantenere le autorizzazioni degli utenti in un database?

2

Qual è il modo accettato di tenere traccia delle autorizzazioni di un utente in un database? Supponiamo che io disponga di un'app Web in cui gli utenti possono pagare per i privilegi. Per usare un'analogia diretta, immagina gli utenti di Github (i membri paganti possono avere repository privati, ecc.) Un modo che vedo di fare è tenere traccia del tipo di utente nel database:

account_type: String

L'altro modo è mantenere una serie di permessi:

permissions: [String]

Quale è il preferito?

    
posta db2791 20.11.2016 - 21:59
fonte

4 risposte

6

Se il denaro è coinvolto, e chissà che cosa il team di marketing immaginerà in futuro, vai con autorizzazioni e ruoli.

Un'autorizzazione è una singola azione nel sistema, come la creazione di un nuovo repository privato. Un ruolo è una raccolta di permessi. Agli utenti può essere assegnato un numero qualsiasi di ruoli. Inserisci una data di inizio e una data di fine in modo da consentire agli utenti di accedere ai ruoli per un determinato periodo di tempo.

    
risposta data 20.11.2016 - 22:48
fonte
2

L'ho visto fatto in molti modi. Credo che se si tratta di un semplice alternatore tra "account gratuito" e "account pagato" verrà eseguito un singolo campo intero 0/1 o enum, mentre se ci sono un certo numero di permessi diversi, probabilmente si vorrebbe usare una bit-string dove ogni singolo bit rappresenta una particolare autorizzazione o impostazione dell'account.

    
risposta data 20.11.2016 - 22:33
fonte
1

Ci sono molti modi in cui ci sono strutture dati:

Variabili

can_edit = true
is_admin = true

Coppie valore-chiave in una tabella di coppie valore-chiave o in un archivio di valori-chiave come mongo

can_edit : true
is_admin : true

Un hash di coppie chiave-valore, ad es. ruby

{
can_edit => true
is_admin => true
}

Una tabella di database per "utenti" con vari campi vero / falso

users
can_edit BOOLEAN
is_admin BOOLEAN

Tabelle di database per utenti e ruoli & quindi un'altra tabella di database che funge da tabella di join per le autorizzazioni, il che significa che avrà colonne per user_id e role_id in essa

mysql> describe users;
+----------+-----------+------+-----+---------+----------------+
| Field    | Type      | Null | Key | Default | Extra          |
+----------+-----------+------+-----+---------+----------------+
| id       | int(11)   | NO   | PRI | NULL    | auto_increment |
| user_id  | int(11)   | NO   |     | NULL    |                |
| role_id  | int(11)   | NO   |     | NULL    |                |
+----------+-----------+------+-----+---------+----------------+

Nell'esempio precedente can_edit e is_admin sarebbero ruoli memorizzati nella tabella dei ruoli, una riga per ogni riga di ruolo avente un id univoco che viene quindi fatto riferimento nella tabella delle autorizzazioni sopra insieme con id_utente per utente che ha quel ruolo.

    
risposta data 20.11.2016 - 23:23
fonte
0

La logica dell'array che hai citato è una soluzione linguistica imperativa, non proprio appropriata per l'archiviazione su un database.

I database relazionali utilizzano la logica dell'insieme, che è in qualche modo simile ai concetti di matrice ma non è la stessa. Pensi su insiemi / tabelle che sono come array estensibili.

Il design del database più comune per il tuo problema (con molte varianti diverse) includerebbe 3 tabelle, prodotto di normalizzazione dei requisiti dei dati:

a) Utenti, campi di base come id_user e login_user più eventuali campi richiesti (ad es. first_name, last_name)

Dati di esempio: id_user login_user 1 admin 2 db2791 3 bruno

b) Autorizzazioni, con campi di base come id_permission e name_permission Dati di esempio:

id_permission name_permission 1 Crea Repo 2 Commit in Repo

c) Utenti - Tabella delle relazioni delle autorizzazioni, con campi base le chiavi esterne id_user e id_permission; quindi contrassegna se disponi di livelli diversi per le autorizzazioni, ad es. can_read, can_write, che potrebbero invece essere autorizzazioni indipendenti

Dati di esempio: id_user id_permission 1 1 1 2 2 2

La mancanza di dati nella relazione implica l'assenza di autorizzazione. Potresti voler aggiungere un flag grant / deny per consentire la rimozione esplicita del permesso.

Un altro schema comune che estende questo, è quello di aggiungere una tabella Risorse (o Securables), cambiando la relazione con l'utente - permesso - risorsa

    
risposta data 21.11.2016 - 18:51
fonte

Leggi altre domande sui tag