Devo usar o nome de usuário ou o ID do usuário para fazer referência a usuários autenticados no ASP.NET

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

  •  08-06-2019
  •  | 
  •  

Pergunta

Portanto, em meu site de aprendizado simples, uso o sistema de autenticação ASP.NET integrado.

Estou adicionando agora uma tabela de usuário para salvar coisas como zip, DOB etc.Minha pergunta é:

  1. Na nova tabela, a chave deve ser o nome do usuário (a string) ou o ID do usuário, que é o número de aparência GUID que eles usam no asp_ tables.
  2. Se a melhor prática é usar esse guia feio, alguém sabe como consegui-lo?parece não ser acessível tão facilmente quanto o nome (System.Web.HttpContext.Current.User.Identity.Name)
  3. Se você sugerir que eu não use nenhum dos dois (nem os campos guid nem userName fornecidos pela autenticação ASP.NET), como faço isso com a autenticação ASP.NET?Uma opção que gosto é usar o endereço de e-mail do usuário como login, mas como fazer com que o sistema de autenticação ASP.NET use um endereço de e-mail em vez de um nome de usuário?(ou não há nada para fazer lá, sou só eu decidindo que "sei" que userName é na verdade um endereço de e-mail?

Observe:

  • Não estou perguntando como obter um GUID no .NET, estou apenas me referindo à coluna userID no asp_ tables como guia.
  • O nome de usuário é exclusivo na autenticação ASP.NET.
Foi útil?

Solução

Eu sugeriria usar o nome de usuário como chave primária na tabela se o nome de usuário for único. Existem alguns bons motivos para fazer isso:

  1. A chave primária será um índice clusterizado e, portanto, a busca pelos detalhes do usuário por meio de seu nome de usuário será muito rápida.
  2. Isso impedirá que nomes de usuário duplicados apareçam
  3. Você não precisa se preocupar em usar duas informações diferentes (nome de usuário ou guid)
  4. Isso tornará a escrita do código muito mais fácil, pois não será necessário pesquisar dois bits de informação.

Outras dicas

Você deve usar algum ID exclusivo, o GUID mencionado ou alguma outra chave gerada automaticamente.No entanto, este número nunca deve estar visível para o usuário.

Um grande benefício disso é que todo o seu código pode funcionar no ID do usuário, mas o nome do usuário não está realmente vinculado a ele.Em seguida, o usuário pode alterar seu nome (o que considero útil em sites).Isso é especialmente útil se você usar o endereço de e-mail como login do usuário...o que é muito conveniente para os usuários (então eles não precisam se lembrar de 20 IDs caso seu ID de usuário comum seja popular).

Você deve usar o UserID.É a propriedade ProviderUserKey de MembershipUser.

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());

Eu usaria um ID de usuário.Se você quiser usar um nome de usuário, tornará o recurso "alterar o nome de usuário" muito caro.

Eu concordo com Palmsey, embora pareça haver um pequeno erro em seu código:

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name)).ProviderUserKey.ToString());

deveria estar

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());

Eu diria que use o UserID para que os nomes de usuário ainda possam ser alterados sem afetar a chave primária.Eu também definiria a coluna de nome de usuário como exclusiva para impedir nomes de usuário duplicados.

Se você estiver pesquisando principalmente por nome de usuário em vez de ID de usuário, torne o nome de usuário um índice clusterizado e defina a chave primária como não clusterizada.Isso lhe dará o acesso mais rápido ao pesquisar nomes de usuário; se, no entanto, você estiver pesquisando principalmente por UserIds, deixe-o como o índice clusterizado.

Editar:Isso também se ajustará melhor às tabelas de membros atuais do ASP.Net, pois elas também usam o UserID como chave primária.

Isso é antigo, mas só quero que as pessoas que o encontrarem observem algumas coisas:

  1. O banco de dados de membros do aspnet É otimizado quando se trata de acessar registros de usuários.A busca de índice clusterizado (ideal) no SQL Server é usada quando um registro é pesquisado usando nome de usuário reduzido e ID do aplicativo.Isso faz muito sentido, pois só temos o nome de usuário fornecido quando o usuário envia suas credenciais pela primeira vez.

  2. O userid guid fornecerá um tamanho de índice maior que um int, mas isso não é realmente significativo porque geralmente recuperamos apenas 1 registro (usuário) por vez e em termos de fragmentação, o número de leituras geralmente supera em muito o número de gravações e edições para uma tabela de usuários - as pessoas simplesmente não atualizam essas informações com tanta frequência.

  3. o script regsql que cria as tabelas de associação do aspnet pode ser editado para que, em vez de usar NEWID como padrão para o ID do usuário, ele possa usar NEWSEQUENTIALID() que oferece melhor desempenho (eu criei um perfil disso).

  4. Perfil.Alguém que cria um “novo site de aprendizagem” não deveria tentar reinventar a roda.Um dos sites em que trabalhei usava uma versão pronta para uso das tabelas de membros do aspnet (excluindo o horrível sistema de perfis) e a tabela de usuários continha quase 2 milhões de registros de usuários.Mesmo com um número tão alto de registros, as seleções ainda foram rápidas porque, como eu disse no início, os índices do banco de dados focam em loweredusername+applicationid para realizar uma busca de índice clusterizado para esses registros e de modo geral, se o sql estiver fazendo uma busca de índice clusterizado para encontrar 1 registro, você não tem problemas, mesmo com um grande número de registros, desde que não adicione colunas às tabelas e comece a extrair muitos dados.

  5. Preocupar-se com um guia neste sistema, para mim, com base no desempenho real e na experiência do sistema, é uma otimização prematura.Se você tiver um int para seu ID de usuário, mas o sistema executa consultas abaixo do ideal devido ao design de índice personalizado, etc.o sistema não será bem dimensionado.O pessoal da Microsoft fez um bom trabalho em geral com o banco de dados de associação do aspnet e há muitas coisas mais produtivas nas quais focar do que alterar o userId para int.

Eu usaria um número de incremento automático, geralmente um int.

Você deseja manter o tamanho da chave o menor possível.Isso mantém seu índice pequeno e também beneficia quaisquer chaves estrangeiras.Além disso, você não está acoplando firmemente o design de dados aos dados do usuário externo (isso também vale para o GUID do aspnet).

Geralmente, os GUIDs não são boas chaves primárias, pois são grandes e as inserções podem ocorrer potencialmente em qualquer página de dados da tabela, e não na última página de dados.A principal exceção é se você estiver executando vários bancos de dados replicados.GUIDs são muito úteis para chaves nesse cenário, mas suponho que você tenha apenas um banco de dados, então isso não é um problema.

Se você for usar o LinqToSql para desenvolvimento, eu recomendaria usar um Int como chave primária.Tive muitos problemas quando tive relacionamentos construídos a partir de campos não-Int, mesmo quando o campo nvarchar(x) tinha restrições para torná-lo um campo exclusivo.

Não tenho certeza se este é um bug conhecido no LinqToSql ou algo assim, mas tive problemas com isso em um projeto atual e tive que trocar PKs e FKs em várias tabelas.

Eu concordo com Mike Stone.Eu também sugeriria usar apenas um GUID caso você rastreie uma enorme quantidade de dados.Caso contrário, uma coluna simples de número inteiro (Id) com incremento automático será suficiente.

Se você precisar do GUID, o .NET é adorável o suficiente para que você possa obtê-lo com um simples ...

Dim guidProduct As Guid = Guid.NewGuid()

ou

Guid guidProduct = Guid.NewGuid();

Estou concordando com Mike Stone também.Minha empresa implementou recentemente uma nova tabela de usuários para clientes externos (em oposição aos usuários internos que se autenticam por meio de LDAP).Para os usuários externos, optamos por armazenar o GUID como chave primária e armazenar o nome de usuário como varchar com restrições exclusivas no campo nome de usuário.

Além disso, se você for armazenar o campo de senha, recomendo fortemente armazenar a senha como um binário salgado e com hash no banco de dados.Dessa forma, se alguém hackear seu banco de dados, não teria acesso às senhas de seus clientes.

Eu usaria o guia no meu código e como já mencionei um endereço de e-mail como nome de usuário.Afinal, já é único e memorável para o usuário.Talvez até abandone o guia (v.discutível).

Alguém mencionou o uso de um índice clusterizado no GUID se ele estivesse sendo usado em seu código.Eu evitaria isso, especialmente se os INSERTs fossem altos;o índice será reconstruído toda vez que você INSERIR um registro.Os índices clusterizados funcionam bem em IDs de incremento automático porque novos registros são anexados apenas.

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