我应该使用用户名还是用户ID来引用ASP.NET中经过身份验证的用户
因此,在我的简单学习网站中,我使用了内置的ASP.NET身份验证系统。
我现在添加一个用户表来保存诸如zip,DOB等之类的东西。我的问题是:
- 在新表中,键应为用户名(字符串)或者用户ID,即用户在" asp_表"中使用的具有GUID外观的数字。
- 如果最佳实践是使用该丑陋的GUID,那么有人知道如何获得它吗?它似乎不像名称那样容易访问(
System.Web.HttpContext.Current.User.Identity.Name
) - 如果我们建议我不使用(不使用ASP.NET身份验证提供的guid或者userName字段),那么如何使用ASP.NET身份验证呢?我喜欢的一种选择是使用用户的电子邮件地址作为登录名,但是如何使ASP.NET身份验证系统使用电子邮件地址而不是用户名? (或者没有什么可做的,只是我决定我"知道" userName实际上是一个电子邮件地址吗?
请注意:
- 我不是在问如何在.NET中获得GUID,我只是将asp_tables中的userID列称为guid。
- 用户名在ASP.NET身份验证中是唯一的。
解决方案
回答
我们应该使用一些唯一的ID,即我们提到的GUID或者其他一些自动生成的密钥。但是,该号码永远对用户不可见。
这样做的巨大好处是,所有代码都可以在用户ID上使用,但是用户名并没有真正与其绑定在一起。然后,用户可以更改其名称(我发现在网站上有用)。如果我们使用电子邮件地址作为用户的登录名,这特别有用……这对用户来说非常方便(这样,如果普通用户ID受欢迎,他们就不必记住20个ID)。
回答
我同意迈克·斯通(Mike Stone)的观点。我还建议仅在要跟踪大量数据的情况下使用GUID。否则,一个简单的自动递增整数(Id)列就足够了。
如果我们确实需要GUID,那么.NET足够可爱,我们可以通过简单的方法获得它。
Dim guidProduct As Guid = Guid.NewGuid()
或者
Guid guidProduct = Guid.NewGuid();
回答
我们应该使用UserID。
这是MembershipUser的ProviderUserKey属性。
Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());
回答
如果用户名是唯一的,我建议使用用户名作为表中的主键,这样做有几个很好的理由:
- 主键将是聚集索引,因此通过用户名搜索用户详细信息将非常快。
- 它将阻止出现重复的用户名
- 我们不必担心会使用两种不同的信息(用户名或者guid)
- 由于不必查找两位信息,这将使编写代码变得更加容易。
回答
我会使用一个用户ID。如果要使用用户名,将使"更改用户名"功能非常昂贵。
回答
如果我们要使用LinqToSql进行开发,我建议我们使用Int作为主键。当我使用非Int字段建立关系时,即使nvarchar(x)字段具有使其成为唯一字段的约束,我也会遇到很多问题。
我不确定这是否是LinqToSql中的已知错误还是什么,但是我在当前项目中遇到了问题,因此不得不在几张表上换出PK和FK。
回答
我也同意迈克·斯通(Mike Stone)的观点。我公司最近为外部客户(与通过LDAP进行身份验证的内部用户相对)实现了一个新的用户表。对于外部用户,我们选择将GUID存储为主键,并将用户名存储为varchar,并且在用户名字段上具有唯一性约束。
另外,如果我们要存储密码字段,我强烈建议我们将密码以盐化,哈希散列的形式存储在数据库中。这样,如果有人要入侵数据库,则他们将无权访问我们客户的密码。
回答
我会使用一个自动递增的数字,通常是一个整数。
我们想要使密钥的大小尽可能小。这样可以使索引变小,也可以使任何外键受益。另外,我们并没有将数据设计与外部用户数据紧密结合(对于aspnet GUID也是如此)。
通常,GUID不能提供良好的主键,因为它们很大,并且插入可能发生在表内的任何数据页上,而不是最后一个数据页上。主要的例外是如果我们正在运行多用途复制数据库。在这种情况下,GUID对于密钥非常有用,但是我猜我们只有一个数据库,所以这不是问题。
回答
我同意Palmsey,
尽管他的代码似乎有一点错误:
Guid UserID = new Guid(Membership.GetUser(User.Identity.Name)).ProviderUserKey.ToString());
应该
Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());
回答
我想说的是使用UserID,以便仍可以更改用户名而不影响主键。我还将用户名列设置为唯一以停止重复的用户名。
如果我们主要是在用户名而不是用户ID上进行搜索,则将用户名设置为聚集索引,并将主键设置为非聚集。在搜索用户名时,这将为我们提供最快的访问权限,但是,如果我们将主要搜索UserId,则将其保留为聚簇索引。
编辑:这也将更好地适合当前的ASP.Net成员资格表,因为它们还将UserID用作主键。
回答
我会在代码中使用guid,并且已经提到过将电子邮件地址用作用户名。毕竟,对于用户而言,它已经是独特且令人难忘的。甚至放弃了Guid(可辩论)。
如果代码中使用了聚集索引,则有人提到在GUID上使用聚集索引。我会避免这种情况,尤其是在INSERT高的情况下;每当我们插入一条记录时,索引将被重建。尽管由于仅添加了新记录,所以聚集索引在自动增量ID上也能很好地工作。