views:

7575

answers:

11

So in my simple learning website, I use the built in ASP.NET authentication system.

I am adding now a user table to save stuff like his zip, DOB etc'. My question is:

  1. In the new table, should the key be the user name (the string) or the user ID which is that GUID looking number they use in the asp_ tables.
  2. If the best practice is to use that ugly guid, anyone knows how to get it? it seems to not be accessible as easily as the name (System.Web.HttpContext.Current.User.Identity.Name)
  3. If you suggest I use neither (not the guid nor the userName fields provided by ASP.NET authentication) then how do I do it with ASP.NET authentication? One option I like is to use the email address of the user as login, but how to I make ASP.NET authentication system use an email address instead of a user name? (or there is nothing to do there, it is just me deciding I "know" userName is actually an email address?

Please note:

  • I am not asking on how to get a GUID in .NET, I am just refering to the userID column in the asp_ tables as guid.
  • The user name is unique in ASP.NET authentication
+13  A: 

You should use some unique ID, either the GUID you mention or some other auto generated key. However, this number should never be visible to the user.

A huge benefit of this is that all your code can work on the user ID, but the user's name is not really tied to it. Then, the user can change their name (which I've found useful on sites). This is especially useful if you use email address as the user's login... which is very convenient for users (then they don't have to remember 20 IDs in case their common user ID is a popular one).

Mike Stone
A: 

I agree with Mike Stone. I would also suggest only using a GUID in the event you are going to be tracking an enormous amount of data. Otherwise, a simple auto incrementing integer (Id) column will suffice.

If you do need the GUID, .NET is lovely enough that you can get one by a simple...

Dim guidProduct As Guid = Guid.NewGuid()

or

Guid guidProduct = Guid.NewGuid();
Dillie-O
+8  A: 

You should use the UserID. It's the ProviderUserKey property of MembershipUser.

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());
palmsey
You have an extra closed parenthesis after .Identity.Name
Marcel Popescu
+5  A: 

I would suggest using the username as the primary key in the table if the username is going to be unique, there are a few good reasons to do this:

  1. The primary key will be a clustered index and thus search for a users details via their username will be very quick.
  2. It will stop duplicate usernames from appearing
  3. You don't have to worry about using two different peices of information (username or guid)
  4. It will make writing code much easier because of not having to lookup two bits of information.
GateKiller
The key problem with using the username is if the user wants to change their username for some reason. If you use username you will have to make changes to multiple tables instead of just one.Note: made this comment then read below and saw someone else mentioned this.
percent20
Other potential issue arise when usernames can be reused over time. For example, let's say you use the username in your custom authorization model. User ASmith is assigned as an administrator. He then leaves the company and his user record is deleted. A new user joins the company and is assigned the username ASmith. You have potentially just given that user admin access without realizing it.
Phil Haselden
+3  A: 

I would use a userid. If you want to use an user name, you are going to make the "change the username" feature very expensive.

jdelator
+1  A: 

If you're going to be using LinqToSql for development, I would recommend using an Int as a primary key. I've had many issues when I had relationships built off of non-Int fields, even when the nvarchar(x) field had constraints to make it a unique field.

I'm not sure if this is a known bug in LinqToSql or what, but I've had issues with it on a current project and I had to swap out PKs and FKs on several tables.

Otto
A: 

I'm agreeing with Mike Stone also. My company recently implemented a new user table for outside clients (as opposed to internal users who authenticate through LDAP). For the external users, we chose to store the GUID as the primary key, and store the username as varchar with unique constraints on the username field.

Also, if you are going to store the password field, I highly recommend storing the password as a salted, hashed binary in the database. This way, if someone were to hack your database, they would not have access to your customer's passwords.

proudgeekdad
+1  A: 

I would use an auto incrementing number usually an int.

You want to keep the size of the key as small as possible. This keeps your index small and benefits any foreign keys as well. Additonally you are not tightly coupling the data design to external user data (this holds true for the aspnet GUID as well).

Generally GUIDs don't make good primary keys as they are large and inserts can happen at potentially any data page within the table rather than at the last data page. The main exception to this is if you are running mutilple replicated databases. GUIDs are very useful for keys in this scenario, but I am guessing you only have one database so this is not a problem.

John Hunter
A: 

I agree with Palmsey, Though there seems to be a little error in his code:

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

should be

Guid UserID = new Guid(Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString());
Schprit
+2  A: 

I would say use the UserID so Usernames can still be changed without affecting the primary key. I would also set the username column to be unique to stop duplicate usernames.

If you'll mainly be searching on username rather than UserID then make Username a clustered index and set the Primary key to be non clustered. This will give you the fastest access when searching for usernames, if however you will be mainly searching for UserIds then leave this as the clustered index.

Edit : This will also fit better with the current ASP.Net membership tables as they also use the UserID as the primary key.

Gavin Draper
A: 

I would use the guid in my code and as already mentioned an email address as username. It is, after all, already unique and memorable for the user. Maybe even ditch the guid (v. debateable).

Someone mentioned using a clustered index on the GUID if this was being used in your code. I would avoid this, especially if INSERTs are high; the index will be rebuilt every time you INSERT a record. Clustered indexes work well on auto increment IDs though because new records are appended only.

iWeasel