我应该使用用户名或用户ID来引用ASP.NET中经过身份验证的用户

时间:2008-08-07 16:19:40

标签: asp.net authentication

所以在我的简单学习网站中,我使用内置的ASP.NET身份验证系统。

我现在正在添加一个用户表来保存他的拉链,DOB等内容。我的问题是:

  1. 在新表中,密钥应该是用户名(字符串)还是用户ID,它是在asp_ tables中使用的GUID查找号码。
  2. 如果最佳做法是使用那个丑陋的guid,有人知道如何获得它吗?它似乎不像名称(System.Web.HttpContext.Current.User.Identity.Name
  3. 那样容易访问
  4. 如果您建议我不使用(不是ASP.NET身份验证提供的guid和userName字段),那么如何使用ASP.NET身份验证呢?我喜欢的一个选项是使用用户的电子邮件地址作为登录,但是如何使ASP.NET身份验证系统使用电子邮件地址而不是用户名? (或者那里没什么可做的,只是我决定我“知道”userName实际上是一个电子邮件地址?
  5. 请注意:

    • 我不是在询问如何在.NET中获取GUID,我只是将asp_ tables中的userID列称为guid。
    • 用户名在ASP.NET身份验证中是唯一的。

12 个答案:

答案 0 :(得分:31)

您应该使用一些唯一的ID,您提到的GUID或其他一些自动生成的密钥。但是,该号码永远不会对用户可见。

这样做的一个巨大好处是,您的所有代码都可以处理用户ID,但用户的名称并不真正依赖于它。然后,用户可以更改他们的名字(我发现在网站上有用)。如果您使用电子邮件地址作为用户的登录信息,这将非常有用...这对用户来说非常方便(那么他们不必记住20个ID,以防他们的普通用户ID是一个流行的用户ID。)

答案 1 :(得分:23)

您应该使用UserID。 它是MembershipUser的ProviderUserKey属性。

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

答案 2 :(得分:12)

如果用户名是唯一的,我建议使用用户名作为表中的主键,这有几个很好的理由:

  1. 主键将是聚簇索引,因此通过用户名搜索用户详细信息非常快。
  2. 它将阻止重复的用户名出现
  3. 您不必担心使用两种不同的信息(用户名或guid)
  4. 由于不必查找两位信息,因此编写代码会更容易。

答案 3 :(得分:5)

我会使用用户ID。如果您想使用用户名,您将使“更改用户名”功能非常昂贵。

答案 4 :(得分:3)

我同意Palmsey, 虽然他的代码中似乎有一点错误:

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

应该是

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

答案 5 :(得分:3)

我想说使用UserID,因此仍然可以更改用户名而不会影响主键。我还要将用户名列设置为唯一以停止重复的用户名。

如果您主要搜索用户名而不是UserID,则将Username设为聚簇索引,并将主键设置为非群集。这将在搜索用户名时为您提供最快的访问权限,但是如果您将主要搜索UserIds,则将其保留为聚簇索引。

编辑:这也适合当前的ASP.Net成员资格表,因为它们也使用UserID作为主键。

答案 6 :(得分:3)

这已经过时了但我只是想让发现这一点的人注意到一些事情:

  1. 在访问用户记录时,优化了aspnet成员资格数据库。当使用lowerusername和applicationid搜索记录时,将使用sql server中的聚簇索引seek(最佳)。这很有意义,因为我们只有用户首次发送凭据时才会提供用户名。

  2. guid用户标识将提供比int更大的索引大小,但这并不重要,因为我们通常一次只检索1条记录(用户),而在碎片方面,读取次数通常会大大超过对用户表的写入和编辑次数 - 人们根本不会经常更新该信息。

  3. 可以编辑创建aspnet成员资格表的regsql脚本,以便不使用NEWID作为userid的默认值,而是可以使用NEWSEQUENTIALID()来提供更好的性能(我已经对此进行了分析)。

  4. 资料。创建“新学习网站”的人不应该试图重新发明轮子。我工作过的其中一个网站使用了aspnet成员资格表的开箱即用版本(不包括可怕的个人资料系统),用户表包含近200万个用户记录。即使有如此多的记录,选择仍然很快,因为,正如我开始所说,数据库索引专注于lowerusername + applicationid peform聚集索引寻找这些记录,一般来说,如果sql正在进行聚簇索引搜索找到1条记录,你没有任何问题,即使有大量的记录,只要你不向表中添加列并开始撤回过多的数据。

  5. 根据系统的实际性能和经验,对我来说担心这个系统的指导是不成熟的。如果您的userid有一个int,但由于您的自定义索引设计等原因系统执行次优查询,系统将无法很好地扩展。微软的人员在aspnet成员资格数据库方面做得非常出色,而且要将重点放在比将userId更改为int更多的工作上。

答案 7 :(得分:2)

我会使用一个自动递增的数字,通常是一个int。

您希望尽可能减小密钥的大小。这使您的索引保持较小并且也可以使任何外键受益。另外,您没有将数据设计与外部用户数据紧密耦合(这也适用于aspnet GUID)。

通常,GUID不会生成好的主键,因为它们很大并且插入可能发生在表中的任何数据页面而不是最后一个数据页面。对此的主要例外是如果您正在运行多重复制数据库。在这种情况下,GUID对于密钥非常有用,但我猜你只有一个数据库,所以这不是问题。

答案 8 :(得分:1)

如果您打算使用LinqToSql进行开发,我建议使用Int作为主键。当我使用非Int字段构建关系时,即使nvarchar(x)字段具有使其成为唯一字段的约束,我也遇到了很多问题。

我不确定这是否是LinqToSql中的已知错误或者是什么,但我在当前项目中遇到了问题,我不得不在几个表上换掉PK和FK。

答案 9 :(得分:0)

我同意Mike Stone的观点。如果您要跟踪大量数据,我还建议仅使用GUID。否则,一个简单的自动递增整数(Id)列就足够了。

如果你确实需要GUID,.NET很可爱,你可以通过一个简单的...

Dim guidProduct As Guid = Guid.NewGuid()

Guid guidProduct = Guid.NewGuid();

答案 10 :(得分:0)

我也同意Mike Stone的观点。我公司最近为外部客户端实现了一个新的用户表(而不是通过LDAP进行身份验证的内部用户)。对于外部用户,我们选择将GUID存储为主键,并将用户名作为varchar存储在用户名字段的唯一约束中。

另外,如果您要存储密码字段,我强烈建议您将密码存储为数据库中的盐渍哈希二进制文件。这样,如果有人要破解您的数据库,他们将无法访问您客户的密码。

答案 11 :(得分:0)

我会在我的代码中使用guid,并且已经提到了一个电子邮件地址作为用户名。毕竟,它已经为用户带来了独特和难忘的体验。也许甚至放弃了指导(v。辩论)。

有人提到在GUID上使用聚簇索引(如果在您的代码中使用它)。我会避免这种情况,特别是如果INSERT很高;每次插入记录时都会重建索引。群集索引可以很好地处理自动增量ID,因为只添加了新记录。