Múltiples tipos de permisos (roles) almacenados en la base de datos como un solo decimal

StackOverflow https://stackoverflow.com/questions/60204

  •  09-06-2019
  •  | 
  •  

Pregunta

Iba a hacer una pregunta aquí sobre si mi diseño para algunas tablas de bases de datos de usuarios/roles era aceptable o no, pero después de investigar un poco me encontré con esta pregunta:

¿Cuál es la mejor manera de manejar múltiples tipos de permisos?

Suena como un enfoque innovador, por lo que en lugar de una tabla de relación de muchos a muchos usuarios_a_roles, tengo múltiples permisos definidos como un solo decimal (supongo que tipo de datos int).Eso significa que todos los permisos para un único usuario están en una fila.Probablemente no tenga sentido hasta que leas la otra pregunta y respondas.

No puedo entender esto.¿Alguien puede explicar el proceso de conversión?Suena "correcto", pero no entiendo cómo convierto los roles a decimal antes de que entren en la base de datos y cómo se vuelven a convertir cuando salen de la base de datos.Estoy usando Java, pero si lo eliminaras, también sería genial.

Aquí está la respuesta original en caso de que se elimine la otra pregunta:

"Personalmente, a veces uso una enumeración marcada de permisos.De esta manera puede utilizar operaciones bit a bit AND, OR, NOT y XOR en los elementos de la enumeración.

[Flags]
public enum Permission
{
    VIEWUSERS = 1, // 2^0 // 0000 0001
    EDITUSERS = 2, // 2^1 // 0000 0010
    VIEWPRODUCTS = 4, // 2^2 // 0000 0100
    EDITPRODUCTS = 8, // 2^3 // 0000 1000
    VIEWCLIENTS = 16, // 2^4 // 0001 0000
    EDITCLIENTS = 32, // 2^5 // 0010 0000
    DELETECLIENTS = 64, // 2^6 // 0100 0000
}

Luego, puede combinar varios permisos utilizando el operador bit a bit AND.

Por ejemplo, si un usuario puede ver y editar usuarios, el resultado binario de la operación es 0000 0011, que convertido a decimal es 3.Luego puede almacenar el permiso de un usuario en una sola columna de su base de datos (en nuestro caso serían 3).

Dentro de su aplicación, sólo necesita otra operación bit a bit (OR) para verificar si un usuario tiene un permiso particular o no".

¿Fue útil?

Solución

Utiliza operaciones bit a bit.El pseudocódigo sería algo como:

bool HasPermission(User user, Permission permission) {
    return (user.Permission & permission) != 0;
}

void SetPermission(User user, Permission permission) {
    user.Permission |= permission;
}

void ClearPermission(User user, Permission permission) {
    user.Permission &= ~permission;
}

El permiso es el tipo de enumeración definido en su publicación, aunque cualquier tipo debe basarse en un tipo de tipo entero.Lo mismo se aplica al campo Usuario.Permiso.

Si esos operadores (&, |= y &=) no tienen sentido para usted, lea sobre las operaciones bit a bit (Y bit a bit y OR bit a bit).

Otros consejos

En realidad, así es como determinamos la autoridad dentro de una aplicación web bastante grande de la que soy el DBA.

Si vas a hacer algo como esto, realmente te beneficiará tener un tabla de números.Hará que tus cálculos sean mucho más rápidos.

La configuración básica incluye las siguientes tablas:

  1. Grupos: para hacer muchos a muchos usuarios y puntos de seguridad.
  2. Puntos de seguridad: que contienen un valor para autorización anónima y otro para usuarios autenticados que no forman parte de un grupo separado.
  3. Tabla de unión de puntos de seguridad de grupo
  4. Una tabla especial de números BitMask que contiene entradas para los valores ^2.Por tanto, hay una entrada para 2 (2) y dos entradas para tres (2 y 1).Esto evita que tengamos que calcular valores cada vez.

Primero determinamos si el usuario ha iniciado sesión.Si no es así devolvemos la autorización anónima para el punto de seguridad.

A continuación determinamos si el usuario es miembro de algún grupo asociado con el punto de seguridad mediante un simple EXISTS usando un JOIN.Si no es así, devolvemos el valor asociado con el usuario autenticado.La mayoría de los valores predeterminados anónimos y autenticados están configurados en 1 en nuestro sistema porque requerimos que pertenezca a grupos específicos.

Nota: Si un usuario anónimo no tiene acceso, la interfaz lo dirige a un cuadro de inicio de sesión para permitirle iniciar sesión e intentarlo nuevamente.

Si el usuario es miembro de uno o más grupos, luego seleccionamos valores distintos de la tabla BitMask para cada uno de los valores definidos para los grupos.Por ejemplo, si pertenecía a tres grupos y tenía un nivel de autorización de 8, uno con 12 y el último con 36, nuestra selección en la tabla Máscara de bits devolvería 8, 8 y 4, y 4 y 32 respectivamente.Al hacer una diferencia obtenemos los números 4, 8 y 32 que enmascaran correctamente el bit a 101100.

Ese valor se devuelve como nivel de autorización de los usuarios y el sitio web lo procesa.

¿Tener sentido?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top