Vários tipos de permissão (funções) armazenados no banco de dados como decimal único

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

  •  09-06-2019
  •  | 
  •  

Pergunta

Eu ia fazer uma pergunta aqui sobre se meu design para algumas tabelas de banco de dados de usuários/funções era aceitável ou não, mas depois de algumas pesquisas me deparei com esta pergunta:

Qual é a melhor maneira de lidar com vários tipos de permissão?

Parece uma abordagem inovadora, portanto, em vez de uma tabela de relacionamento muitos-para-muitos users_to_roles, tenho várias permissões definidas como um único decimal (tipo de dados int, presumo).Isso significa que todas as permissões de um único usuário estão em uma linha.Provavelmente não fará sentido até que você leia a outra pergunta e resposta

Não consigo entender isso.Alguém pode explicar o processo de conversão?Parece "certo", mas não estou entendendo como converto as funções em decimal antes de entrar no banco de dados e como ele é convertido novamente quando sai do banco de dados.Estou usando Java, mas se você apagasse, também seria legal.

Aqui está a resposta original, caso a outra pergunta seja excluída:

"Pessoalmente, às vezes uso uma enumeração sinalizada de permissões.Desta forma você pode usar operações AND, OR, NOT e XOR bit a bit nos itens da enumeração.

[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
}

Então, você pode combinar várias permissões usando o operador AND bit a bit.

Por exemplo, se um usuário puder visualizar e editar usuários, o resultado binário da operação será 0000 0011, que convertido em decimal será 3.Você pode então armazenar a permissão de um usuário em uma única coluna do seu banco de dados (no nosso caso seriam 3).

Dentro da sua aplicação, você só precisa de outra operação bit a bit (OR) para verificar se um usuário tem uma permissão específica ou não."

Foi útil?

Solução

Você usa operações bit a bit.O pseudocódigo seria 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;
}

Permissão é o tipo enum definido em sua postagem, embora qualquer tipo precise ser baseado em um tipo semelhante a um número inteiro.O mesmo se aplica ao campo User.Permission.

Se esses operadores (&, |= e &=) não fazem sentido para você, leia sobre operações bit a bit (AND bit a bit e OR bit a bit).

Outras dicas

Na verdade, é assim que determinamos a autoridade em um aplicativo Web bastante grande do qual sou DBA.

Se você for fazer algo assim, você realmente se beneficiará em ter um tabela de números.Isso tornará seus cálculos muito mais rápidos.

A configuração básica inclui as seguintes tabelas:

  1. Grupos - para fazer muitos para muitos usuários e pontos de segurança
  2. Pontos de segurança – que contêm um valor para autorização anônima e outro para usuários autenticados que não fazem parte de um grupo separado
  3. Tabela de junção do ponto de segurança do grupo
  4. Uma tabela especial de números BitMask que contém entradas para os valores ^2.Assim, há uma entrada para 2 (2) e duas entradas para três (2 e 1).Isso nos evita ter que calcular valores todas as vezes.

Primeiro determinamos se o usuário está logado.Caso contrário, devolvemos a autorização anônima para o ponto de segurança.

Em seguida, determinamos se o usuário é membro de algum grupo associado ao ponto de segurança por meio de um simples EXISTS usando um JOIN.Caso contrário, retornamos o valor associado ao usuário autenticado.A maioria dos padrões anônimos e autenticados são definidos como 1 em nosso sistema porque exigimos que você pertença a grupos específicos.

Observação: Se um usuário anônimo não obtiver acesso, a interface o direcionará para uma caixa de login para permitir que ele faça login e tente novamente.

Se o usuário é um membro de um ou mais grupos, então selecionamos valores distintos da tabela BitMask para cada um dos valores definidos para os grupos.Por exemplo, se você pertencesse a três grupos e tivesse um nível de autorização de 8, um com 12 e o último com 36, nossa seleção na tabela Bit Mask retornaria 8, 8 e 4, e 4 e 32 respectivamente.Fazendo uma distinção, obtemos os números 4, 8 e 32, que mascaram corretamente o bit para 101100.

Esse valor é retornado como o nível de autorização dos usuários e processado pelo site.

Faz sentido?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top