What are the fields that the user table should contain from the security/authenication perspective? - sql-server

When designing user table what would be the must have fields from the security/user authentication point of view for a Web based Application (.NET and SqlServer 2005)
I came with with the following fields:
userID
username -- preferably email
passwordHash
onceUsePassword -- to indicate that the password should be changed after login
alternativeContactEmail
userStatusID -- FK to a lookup table with statuses like: active, diabled etc
dateCreated
dateUpdated
lastPasswordUpdate
lastLogon
-- and then the rest like :forename, surname etc which are not of the interest in this question
Am I missing something?
Is standard identity (INT) sufficient for userID or should the GUID be used instead (the userID is not going to be exposed anywhere)?
EDIT:
I am limited to the use of .NET 1.1
(don't ask...)
The salt info will be merged with passwordHash
the account would be unlocked by sending a temporary, single use system generated password to the user email address (hence onceUsePassword field)

Why not just use the built-in SQL Membership Provider if you're using SQL Server anyway? It's much better than rolling your own since it's been tested by a lot of people.
In any case, you should think about adding a salt field your table.
Salting
Update:
.NET 1.1? I guess that answers my question. Is your application for the consumption of the general public? If so, you might want to add a way for them to unlock their accounts via a secret question.

onceUsePassword -- to indicate that
the password should be changed after
login
If you have to explain it that much, you should rename it. Something like "forceChangePasswordOnLogin".

You should add a "salt" field to use password salting to avoid dictionary attacks with rainbow tables if your database ever got compromised.
I'm not sure what you mean by "The salt info will be merged with passwordHash". Does that mean that the same salt is used for all password hashs? Would make more sense to generate a random salt for each hash, and store it in a separate field.

Related

SQLite: Individual tables per user or one table for them all?

I've already designed a website which uses an SQLite database. Instead of using one large table, I've designed it so that when a user signs up, a individual table is created for them. Each user will possibly use several hundreds of records. I done this because I thought it would be easier to structure and access.
I found on other questions on this site that one table is better than using many tables for each user.
Would it be worth redesigning my site so that instead of having many tables, there would be one large table? The current method of mine seems to work well though it is still in development so I'm not sure how well it would stack up in a real environment.
The question is: Would changing the code so that there is one large database instead of many individual ones be worth it in terms of performance, efficiency, organisation and space?
SQLite: Creating a user's table.
CREATE TABLE " + name + " (id INTEGER PRIMARY KEY, subject TEXT, topic TEXT, questionNumber INTEGER, question TEXT, answer TEXT, color TEXT)
SQLite: Adding an account to the accounts table.
"INSERT INTO accounts (name, email, password, activated) VALUES (?,?,?,?)", (name, email, password, activated,)
Please note that I'm using python with Flask if it makes any difference.
EDIT
I am also aware that there are questions like this already, however none state whether the advantages or disadvantages will be worth it.
In an object oriented language, would you make a class for every user? Or would you have an instance of a class for each user?
Having one table per user is a really bad design.
You can't search messages based on any field that isn't the username. With your current solution, how would you find all messages for a certain questionNumber?
You can't join with the messages tables. You have to make two queries, one to find the table name and one to actually query the table, which requires two round-trips to the database server.
Each user now has their own table schema. On an upgrade, you have to apply your schema migration to every messages table, and God help you if some of the tables are inconsistent with the rest.
It's effectively impossible to have foreign keys pointing to your messages table. You can't specify the table that the foreign key column points to, because it won't be the same.
You can have name conflicts with your current setup. What if someone registers with the username accounts? Admittedly, this is easy to fix by adding a user_ prefix, but still something to keep in mind.
SQL injection vulnerabilities. What if I register a user named lol; DROP TABLE accounts; --? Query parameters, the primary way of preventing such attacks, don't work on table names.
I could go on.
Please merge all of the tables, and read up on database normalization.

Consistency in a Login Model using the Google Cloud Datastore

I'm trying to get my head around a login model that uses several authentication methods.
1.) For example, when a new user tries to log in with OpenID my backend is going to insert two entities into the datastore:
Insert a new user, where the automatically inserted id will be his $userId
(kind: User, id: autoId)
Insert a new login that is linked to the $userId
(kind: AuthOpenid, name: $openId), Property(userId: $userId)
This will allow me to make lookup by key requests when a user tries to log in, which enforces strongly consistent data, right?
The idea is that one user can have many logins (like stackexchange) and I don't have to worry about write/read limits because no entities have ancestors while still enforcing consistency.
2.) On a related note: Assuming my users are allowed to pick a username once they have provided an authentication method, how do I efficiently check if a username is taken?
My idea was to insert a new entity for every picked username.
Insert a new username
(kind: Username, name: $username)
Now I can simply make a lookup by key request to see if a username is taken. As far as I know, common lookups will be stored in memcache anyways, so this should be efficient, right?
I could also reverse the procedure and just attempt to insert a username and see if it fails.
1) Your approach looks good. As you've noted, Lookup operations (lookup by key) are guaranteed to return consistent results.
You're also correct that by putting each AuthOpenid entity in its own entity group (no common ancestor), you will avoid the write throughput limit of 1 write/second on any particular entity group (there's no corresponding limit on rate of entity group creation).
2) This will also work, but you will need to execute the read and write operations as part of a transaction. This ensures that if two users try to reserve the same username, only one of them will succeed.
In Cloud Datastore, an insert mutation will fail if an entity with the same key already exists, so this will also work.
(Note that this is different from the put() operation in the App Engine Datastore which uses upsert semantics.)

Should I just store email when its being used as username?

When create a user registration system, I'll be using user's email as the username.
When creating the database schema, should I then treat them as 2 separate fields or should I just treat them as 1?
eg.
USER_TABLE {USER_ID, USERNAME, FNAME, LNAME, EMAIL}
or
USER_TABLE {USER_ID, USERNAME, FNAME, LNAME}
I would think the only argument to store 2 fields separately (even when they are the same) is for some kind of future-proofing if we ever decide to let user create a username that is not an email?
Thoughts?
I would avoid premature optimization and use only one field. If you ever need to have 2 fields, it's easy to create and populate one.
If you believe that there is a reasonable possibility that you might want to allow users to start creating user names that aren't email addresses, then keeping separate email and user_id columns is a good idea. This is especially true if you are building a new system.
I have a maxim in system design: "If someone has thought of the idea, it will eventually happen."
By this I mean that it is often a mistake to think "our business rules will never change in area X". Business rules change - a lot.
You can always add a new field to your table later on to distinguish email from user_id. Adding a column is easy. What will be much harder will be changing all of the code you've written that uses the original user_id column for email purposes. This is why I say it's a good idea to build the distinction between user_id and email into your code from the outset.
You could include both attributes but add a constraint ("check" constraint) to guarantee that username and email are the same. Business logic that requires user name or email can then be written against the appropriate attribute and if and when you need to make them independent you can just drop the constraint.
Don't forget the uniqueness constraint for user name and/or email.

stuck on database design for user management app

I'm trying to write up a user management app, but getting confused about how to structure the database properly.
I think the database design would be structured something like this:
Users
user_id
first_name
last_name
email
Accounts
account_id
ldap_access
drupal_access
billing_app_access
facebook_access
Notes
note_id
description
date_added
And I believe the mapping would go like this:
One user can have one set of accounts (1:1)
One set of accounts can have many users (1:m)
One set of accounts can have many notes (1:m)
Many Notes can have Many Sets of Accounts (m:m)
Is this the correct way to structure the database? I'm really confused since I would like the applications fields be a boolean true/false for that particular user. (If they have an account on there or not), and the notes would correspond to EACH of the fields within the Accounts database. (ie: note_id:1 would correspond to user johndoe, application: facebook, note_description = "user no longer has facebook")
Does this make sense?
Any help would be greatly appreciated!
Mayby something like this:
I still don't understand all your needs.
I prefer this design (used in many system like Windows or Oracle)
Table
User
User-Role
Role
Access
Application
Note (still wonder what this for)
Role useful if you have many user with similar characteristic.

Should I use a number or an email id to identify a user on website?

I have a web app where I register users based on their email id.
From a design/ease of use/flexibility point of view, should I assign a unique number to each user or identify user based on emailid?
Advantage of assigning unique number:
I can change the login itself at a later point without losing the data of the user(flexible).
Disadvantage:
I have to deal with numbers when using the sql command line(error prone).
Which is better? Do you see any other issues that need to be considered for either scheme?
The identity of your users should be unique and immutable. Choosing the email address as identity is not a good idea for several reasons:
The email is one facet of the user's identity that can change at any point in time.
You might decide to allow more than one emails.
You might decide to add other facets, like OpenID or Live ID, or even just old plain username.
There's nothing wrong with allowing multiple identityies to share the same email facet. It is a rare scenario, but not unheard of.
Normalizing the email address is hard and error prone, so you might have problems enforcing the uniqueness. (Are email addresses case sensitive? Do you ignore . or + inside emails? How do you compare non-english emails?)
Btw, using the email as a public representation of the user identity can be a security and privacy problem. Especially if some of your users are under 13 years. You will need a different public facet for the user identity.
Use both.
You have to add an id because you really don't want other tables to use the email address as a foreign key.
Make the email address unique so that you can still use it to identify a user with sql command line.
Unique number - ALWAYS!
But keep the number hidden from the user.
The user should be allowed to change their email. If this is used as the primary identifier then it can cause lots of complications when the key is used in multiple tables.
You should have another identifier other then the users email address which is not visible to the user and never changes. You should then enforce uniqueness on the email address so it can be used as a candidate key.
You will find that users will want to change their email address, or anything really which they can see, so you should as good practice have an identifier which cannot be changed.
Dealing with numbers in sql command object would not really be any more error prone then using the actual email address, if anything I would think it would be less error prone.
Your disadvantage is not a disadvantage. Using numbers with sql is not more or less a problem than using emails or anything else for the matter.
On the other hand your advantage is quite a strong one, you might want to associate users with each other, different emails with one user account, etc. and always using the email will make things harder.
Think also of urls including user identication, an ID is much easier to handle there than an email where you have to think about the proper url endocing.
So in favour of flexiblity and ease of use, I would strongly recommend a unique userID.
Just some points to consider.
How will you validate the email address?
How do you ensure that it is really unique (I don't always use my real address e.g. m.mouse at disney.com
I like to use a unique key generated by the database to identify the record and then add attributes which are out of my control separately
A person's email can change but the id will not
Unique numbers. As well as the reasons identified, I think it would be less error prone than using an email address. Shorter, no funny characters, easier to validate, etc.

Resources