Looking to create a database table that saves user information (primarily user and password).
Is the best way to hash (password) and user?
Should I encrypt the name of user too?
If i have a table of passwords and another with users data, how i can associate/link them?
The login is not the problem, the question is how to associate the tables (table of passwords and table of data for each user)
Thanks
You basic User table would look something like this:
User Table
-------
id username password
1 mike ##$90sDfsa
Where the password is a hashed version (with a salt) of my password.
You should of course hash the password before storing it. Ideally with an unique salt.
As a hash function you should not use something like SHA-*, because the cryptographic hash functions are designed to be fast. This makes it easy for someone getting the hash to try a large number of possible passwords very fast.
Use a password hash function like bcrypt which is designed to be arbitrarily slow.
The login is not the problem, the
question is associate the tables
(table of passwords and table of data
for each user)
To associate the tables you can work with relations:
http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html#04
How to create relationships in MySQL
I would store the hashed and salted password in the table with the rest of the users data. If you really want to store the passwords in a seperate table store the user id with it to associate passwords with users. In general use a strong hashing algorithim e.g. SHA251 and salt the passwords to prevent rainbow table attacks. I don't think that you should need to hash the username.
As I commented above, I would just hash the password.
Also, why are you storing users and passwords in a separate table? They are related, and should be in the same table. Data such as addresses would belong in a separate table.
You can use surrogate keys to do the relation between the tables, if you absolutely must have two tables, one with hashed/salted passwords, the other with user information.
You could have a setup like this:
CREATE TABLE users (USER_ID INTEGER,
PASSWORD_ID INTEGER,
USER_ATTRIBUTE VARCHAR(30));
CREATE TABLE passwords (PASSWORD_ID INTEGER,
PASSWORD_HASH VARCHAR(255));
PASSWORD_ID is the surrogate key, you use it in the users table to reference the value in the passwords table. You can join the tables together with a SQL query:
SELECT *
FROM users INNER JOIN passwords
ON users.PASSWORD_ID = passwords.PASSWORD_ID;
Related
I have a simple user and group database.
User: uid(pk), name, password ( don't worry about password in plain)
Group: gid(pk), name, owner_uid
Member: uid (fk), gid (fk) ( a user can belong to multiple group)
Now, I do not trust my database administrator and want to encrypt/secure specific coloumns so that db admin cannot be able to add any existing uid to any gid. How I could modify my scema and which coloumn I should encrypt.
I have a encryption key which is assumed to stay secure and I wanted to utilize sql queries also so cannot complete encrypt the tables and store as blob.
I think you can not perform this requirement with database constraints. You can manage it by programming. However if you write some triggers to handle it, your (bad) administrator can access triggers too.
Add an extra column to Member like key_info.
In Insert: make a hash code (like sha256Hex) with combination of uid and gid and specific salt. And insert with uid and gid into Member.
In Selects from Member: you have an extra difficulty. You should select the records (from Member) that have correct hash code.
If you have a big and complex salt and your administrator can not access the salt (as you said in comments), he/she can not find the codec algorithm. So if he/she added some records into Member, your codes ignore the added record in selects, because the key_info can not be true.
I have an application that authenticate with LDAP and returns a JWT with the sAMAccountname of the logged user.
This application have a MySQL database where I'd like to store the user in different tables (fields like createdBy, updatedBy, etc.) and I was wondering what is the correct way of handling this:
using the sAMAccount name as identifier (so the createdBy will be a VARCHAR(25))
using a link table to match the sAMAccountname with an autoincremented identifier
Normally I would choose the "id" way, it's faster and easier to read in my opinion, but I'm not really into linking users from LDAP dictionary and changing their id in my database, so honestly I would choose the first option.
What are the pro/cons of using a string as uid ? In my case it's likely to be only for statuses like updatedBy, cratedBy, deletedBy etc. so I won't have hardlinks between multiple tables using an user identifier.
I think you should create user table with a surrogate primary key (autoincrementing one) and make unique index on sAMAccount column.
Natural primary keys are good because they just naturally describe a record they point to. But the downsize of using them is that they consume too much space in the index. Index lookups / rebuilds are slower. Tables consume more space also.
I'd connect everything using an id as primary key.
ONe thing is that the sAMAccountName is not necessarilly unique. Think of a user changing her or his name. The sAMAccountName might then change but it's still the same user. When you connect everything via an ID you can change the sAMAccountName-field without breaking everything.
But that's just my 2 cent
I want to know what is best table structure and indexes for users table (login by email and password) for best performance.
I don't want to use usernames.
I want to login with unique index (for better performance) with user email.
Maybe best performance will be unique index for email and password together.
Problem is that I want to be email indexed as unique for faster login.
But in this case bad user can prevent another user to register knowing his email.
The only idea I could think of some sort of unique email and password hash in one unique column. But I want know how its done the best.
Part of my user table index structure (DB is MySQL)
user_id - PRIMARY
email - UNIQUE
password
verified (after verify email)
Simple solution:
Send verification email with link to cancel registration (I didnt register)
I am designing a database for MySQL to create a relationship between two users of an application. I am unsure of the best way to store the particulars of this relationship, though I currently intend to use one record per relationship in a link table called RELATIONS. Each user has basic data like their name and occupation stored in the USERS table, and more specific personal data stored linked by FKs in other tables, which we'll say are called OTHER1, OTHER2, and OTHER3, which will all contain some other data to be shared, we'll say each in a field called [Data] and identified with ID and USER_ID.
The difficulty is that the application allows users to specify what basic and advanced data that they show to each user, and vice versa. The RELATIONS link table needs to have FKs to USERS for the two users to set up the relationship, but I don't know how best to specify what data each user is able to share, because virtually all of the data that the database stores is stored optionally but all needs to possibly be hidden from a user that doesn't have permission to view it. The second user should be able to see if there is data there, however, so that he might request permission to view it.
My model for RELATIONS at this point looks like this:
RELATIONS
ID
USER_ID1
USER_ID2
USER1OTHER1_ID [(Value), Unshared, Null]
...
USER1OTHER100_ID [(Value), Unshared, Null]
USER2OTHER1_ID [(Value), Unshared, Null]
...
USER2OTHER100_ID [(Value), Unshared, Null]
So USER1OTHER1_ID will contain the FK to OTHER1 if User1 has shared it with User2, will be "Unshared" if it's present but unshared, and Null if User1 has no data in OTHER1. Same for USER2OTHER1 for sharing with User1. I don't like having a massive field array, though, and I don't like how I'd have to update all the relations if User1 later decides to add data to OTHER1. Is there a simpler and more normalised way of representing this?
I believe the normalized approach would be to only store whether userA has permissions to view the userB's data and not add FK references to it in the Relations table because you already have references to userB's data somewhere else. By storing additional references in the Relations table you are duplicating data and will have to ensure that it stays synchronized as you described in your question which will probably be an ongoing maintenance hassle and one more thing you have to keep in mind whenever you refactor your code.
If you only store permissions (no fks) in the Relations table you would join on a table (User?) to get the User's shared data or to see if it exists depending on the permission.
As far as having an excessive number of columns on the relations table, I don't think you will have enough to see a real degradation when querying the table (you could correct me on this). For clarity sake in the db code as well as your application code, I think you are better off to have a column for each permission than to try to find a short cut such as combining them in a clob or something.
The most succinct way I can readily imagine is to store one INT with the relationship, which is a bit-wise representation of the permissions; with the interpretation of that INT in the code. The INT will need as many bits as you have unique permissions, and then define constants for each of them. I'm not sure what language you are implementing in, but there about a few ways to skin this cat...
So, some pseudo-code might look like this:
define RELATION_PERMISSION_SEE_MY_PHOTOS = 1;
define RELATION_PERMISSION_SEE_MY_FRIENDS = 1<<1;
define RELATION_PERMISSION_SEE_MY_EMAIL = 1<<2;
and then build some arrays of supporting info (like localized strings, etc) to build your interface with, and then do something like this to modify it:
int new_permission = 0
foreach(user-selected-permissions as selected_permission) {
new_permission |= selected_permission
}
my_relation_model.permissions_flags = new_permission
one way would be to use essentially key value pairs..
similar to this:
user_1_id
user_2_id
field
privilege
.. because virtually all of the data that the database stores is stored optionally ...
Considering this, I would suggest 6NF for all user attributes.
The User table serves as an anchor and ideally holds only UserID.
Each user attribute has its own table with only UserID and the attribute value (6NF); a row exists only if the attribute is specified (all attribute values are NOT NULL).
Each attribute has also a sharing table with only OwnerID, VisitorID. A row exists only if the owner shares the attribute with the visitor.
In this model, a user can share only attributes that do exists. If you want to allow sharing of not specified attributes, point the OwnerID to the User table too.
To make thing simpler you can (should) create a view(s) for user data.
I am creating a simple web application.
Is it wrong to identify user by it's user name even in the application low level?
For example, say I have a authentication token table that has three columns: token, userID, expDate.
Will it be wrong to put the user username in userID column?
Do I have to worry about the fact that everybody knows the user ID in my DB?
No, I don't think there's anything wrong with that particularly. I've seen that in practice at very big sites - just make sure that you have a unique constraint and index for that value (better, make it the primary key). Also, consider that using the username as their ID means you can't let the user change their username later without breaking existing links (say, if your user shares their user page externally).
I'm not sure, but there might be some overhead from using a string instead of a number.
Also it could be a hassle to update other database tables if a user's username ever changes.