How to invisibly identify user account type of user at login? - authentication

I have started building a web app that has different user types - including Admins and Customers, and I want each account type to have its own users db table (sessions system etc), but with the same log in page.
The Admins don't sign up - they are issued an account, whereas the Customer sign up on a page dedicated to creating their account, so at this time and in the future, every user account type will have its own sign up page.
Yet all user account types ie Admins and Customers, should be able to sign in from the same page - without any differences - in the log in form ie no drop down to select user account type being logged into.
My goals are to have:
all user account types (3+) log into web app via same form,
no need for any visible user account type identifier eg in the formatting of username,
as secure as possible 'invisible' user account type identifier.
One solution I've thought of is: hashing the passwords differently per user account type, but with some constant in the hash that can be read on sign in to identify the user account type, that then points the log in process to the right db for that user, but that would require some kind of constant in the hashed output... and I'm stuck. Am I on the right track?
Does anyone know of a script/how-to/or article that covers such a process somewhere?
This must be used in a lot of current web apps.
Thanks

Where we've had to implement multiple account types (in big systems I should stress) we always settle on a general (Users) table to supplement the additional tables (Administrators, WebUsers, Suppliers etc)
The Users table would link to either an Administrator, WebUser etc and any 'generic' functionality (i.e. login, logs, recordlocks) would link back to the generic Users table.
Then from a Users record you can deduce what type of account it is and decide what they can/cannot do.
I should stress though that this is only because the structure of these tables is so different that they cannot all be stored in the same table. If there's only 1 column different, for instance, you don't need to do all this.

Related

Database structure for multiple authentication sources of users in a web app

I'm trying to work out how to structure a database schema that allows me to have multiple authentication sources for the same end-user.
For example, my web app would require users to sign in to utilize many of the functionality of features of the app. However, I do not want to be responsible for storing and authenticating user passwords.
I would like to outsource this responsibility to Google, Facebook, Twitter and similar identity providers.
So I would still need a database table of users, but no column for a password. However, these are authenticated would not be my concern. But I would still need to somehow associate my user with the identity providers user id. For example, if my user signs up with Google, I would store the users Google ID and associate this with my user. Meaning next time the user makes an attempt to login and is successfully authenticated at Google, I would make an attempt to find any user in my system that has this associated user id.
I've been trying to look for some common and recommended database structures, with no luck. Maybe I'm searching for the wrong terms for this because I cannot imagine that this is an uncommon way to do it. StackOverflow seems to do something similar.
The way I imagine it, it would allow me to associated multiple authentication sources for one app user. Meaning once I've signed up with Google, I can go to my settings and associate another account, for example, a Facebook account.
How should I go about achieving this in a flexible and clean way?
Thanks.
You need to know what data you have to save in your db to authenticate a user with a third party login.
For example, once I used Google to login users in my app, I save Google user id first time a user logs in and get data the next time.
You could have an entity with third party providers, so you will create a table with 2 values, user_id (your user data) and provider_id (Google, facebook, twitter...).
If you are going to use just one provider then you could add provider_id field to your users table.

Can the Auth0 User ID change over time?

Theoretically speaking, if I wanted to base my Users database table on the Auth0 returned data and maintain a unique ID in my Users table based on the Auth0 user profile id, will I ever encounter a situation where the Auth0 user id has been changed? If so, what are the situations when a user id changes?
The simple answer here is that the User Id will not change after creation for a given user profile in Auth0. However, there are a few other factors to consider, in particular:
Namespacing userids
Account linking
Auth0 will place a connection type prefix in-front of userIds to effectively namespace just the Id part - this is done with a pipe. For example, auth0|12345 or auth0|MyCustomDB|12345 etc. You need to ensure you use the entire userId, and not just the numeric value after the last pipe. The reason for this, is to ensure there are no collisions between Ids in IdP/Datastores in which Auth0 is the Service provider, & not the Identity Provider.
With regards to account linking, if you have two separate User Profiles - each has its own UserId. When you account link, one will become effectively the "primary" or "top-level" user profile, and the other profile becomes sub-ordinated as a "secondary" identity. And you can link multiple user profiles together as a single user profile in this way, but only one shall be the primary. You could consistently account link, so for example the DB Connection remains the primary, or you may just make the most recently created user profile (with a shared "email" in common to another profile) the primary... In this situation, the "tertiary" user profiles will retain their original userId, but if you were querying for the user profile only (and not trawling the identities array for that user profile also), then the effect on the search would appear to be the userId had changed. In actual fact, this is because what was originally a "top level" user profile, is now nested inside another use profile.
Finally, and slightly orthogonal to your original question - but where you state if I wanted to base my Users database table on the Auth0 returned data, hope here you were not referring to using the Auth0 user profile userId as a primary key in say a relational database. You would be better served creating a Surrogate key (unique key with no business meaning / outside dependency) as your primary key, Then store the Auth0 userId as a separate attribute on each tuple.
Hope the above made sense, please leave comments below if still unsure.

What is a good practice when setting up a users table? Looking at some newbie tutorials, but not sure how to "really" do it right

I'm tinkering around with building a rest API that connects to a database. I'm following tutorials, but the table set ups are all really basic and one of my issues has been that in the "real world" the way its done is a lot more complex and different :(
However, I'm wondering for my actual application (really small) how can I properly set up the User table?
For example, I have set the primary key to userid because that should never be changing. Is it fine to use long for the userid?
Also, is it fine to lump a bunch of things together that are related to the user.. in the User table? I know its a stupid question.. For example, I want to know if the user has signed up for the service, so isMember. Or, is the user signed up for fast service, so hasFastService. Or, should these things be put into a UserAttributes table by the userid?
Finally, I looked up UUIDs and I'm wondering where those fit in, in which scenarios, etc.
Thanks
I'll try to answer this based on my own experience of creating users table in a project recently. The things you have to take care are basically these:
Authentication: Determine your login process and things like credential fields, user types (admin/guest/normal), whether OAuth is required or not, etc. before creating the users table. For example, whether you need a username/password to authenticate or email/password or either "username or email" with a password. The modern practice is to do away with a "username" since its redundant - an email is unique and acts as a username for all intents.
OAuth: If you are giving facebook/google/twitter logins, make provisions for that in your users table. How will you determine whether the user was a normal signup or a social login signup? A field such as "login_method" or something is useful in this regard. A second field called "user_type" maybe created for identifying the type of user account: admin/guest/employee/etc.
Profile fields: Its upto you to determine profile variables. In my last project, I used a few fields like FirstName, LastName, Theme, Timezone, etc. for the profile, but your mileage may vary.
For user-ids, it is usually best to have an auto generated integer primary key which is available in all modern databases.
Needless to say, never store the actual password in the password field. Just has your password and store the has instead. When the user logs in, you can hash the user-input and compare with the user table value.
Finally, DON'T confuse the user table by including related data like clients, employees, etc. All clients are users, but all users are not clients! Keep your design flexible, so as to include all kinds of users like admins, employees, etc.

Yii - multiple databases with one user authentication

I am facing a problem trying to develop an application in Yii (v=1.1). Client wants the application to has multiple databases (one per his customer). That means that we will have unknown number of databases. Also He wants to have only one user authentication system - regard of it, users would have the choise (and the privilleges) to belong in many databases. So I am considering about the way which it could be developed.
Do you have faced something like this?
Well you should first better define your goal because it is not that clear to me what you want to accomplish, but how I see it.
Decide where you want to store the users:
Should the same user be able to connect using the same login info to two different customer databases?
Do you need to manage all users of all customers from one single place?
You could have the following situations:
Store users only in one common database, not in customer databases:
when logging in tell Yii to use the "common" database for the User model
you could have also a common application that handles user management
you could also provide the customer with the possibility to manage his own users
you could either have a "customer" field in the Users table to indicate to what customer it belongs, or you could have a "users_customers" table and after the login screen prompt the user with a "choose customer" screen, so one unique User can login to multiple Customers
Store users only in the customer databases:
if you don't need for a common place to manage users, or don't need to share them between customers, simply have a User table in every Customer database, this way user "alex" could exist in both databases with different login information
here you could simply add another field in the Login form (yes I've saw one application that does it) for example instead of Username and Password fields, ask for "Office, Username and Password", and the Office would be the name of the Customer database. Or you could even use only Username field and force users to enter something such as "alex#office" as Username, then you split that by "#" and you know to what office it belongs.
then simply use that information both on Login screen and on session to tell Yii what customer database to connect to
So as you see it could be done in different ways. Once you choose your way, you would need a implementation.
If you don't know how to do the implementation maybe I could provide more technical information related to Yii.

User authentication design, are users people?

The application is written in Ruby on Rails but the problem I am facing is more a design matter than language related.
the system provides service to a number of users to maintain a registry. So it relates persons to things. As such it has a model called Person representing owners and it has a model called User representing those who manage the registry.
Now a new requirement has arisen to allow People to log in and be able to change personal details which it was not required for the original design.
The question is how to refactor the application to allow this new requirement in?
One easy solution is to create Users for each person who request login credentials and link user to person entity but that is not very DRY as some fields such as firstname, surname etc. are in both classes and in particular, that is precisely the data people will be able to change. Besides User and Person are stored in separate tables.
The other possibility I was considering is to make one to extend the other but having data in separated tables it makes it a bit messy. Additionally the logical extension would be User <- Person as an user is (generally) a person but thinking on the implementation Person <- User is quite a lot easier.
One last option could be to scrap User and move login credentials into Person leaving logon fields empty for those who won't log in and half of the fields empty for those just login in.
Can you think of a better solution?
You could think about how this should ideally work if you were to write the application bottom-up, and then figure out how to make a reasonable compromise between that and your current setup. Here are some generic inputs.
As authentication is involved, you need an "Identity" that can be authenticated. This can be e.g. an email address and an associated password, with email verification.
An Identity can potentially be associated to multiple "Roles" and someone authenticated with the identity can choose which role to perform, e.g. "I am now an administrator" vs. "I am now a regular site user", and the role defines the user's current rights for the logged in identity. Or if you don't need that level of complexity, you can say that an Identity is a (single) Role.
You need some tracking between possible "Rights" and the Role the user is performing. E.g. the simplest setup could be the Identity or Role has some boolean can_edit_profile or can_modify_registry properties.
Whenever a user attempts to perform an action which requires certain Rights, it is simply a matter of looking up the corresponding rights set for the Role being performed by the user, to check whether the user is allowed to proceed.
For your application this may just involve adding a 'can_change_registry' property for your user objects, and check whether that property is True for any code accessing that part of the site.