User model design when using OAuth - ruby

I'm currently building a web app (my first), and wanted to include OAuth capability so that users can log in via twitter and facebook. I'm building it in Sinatra, and have looked at the OmniAuth gem, which seems to be just right for the job. The issue I having is redesigning the User model.
Currently I have the usual first name, last name, username, email and password, with the username being unique so that I can use it for the ID, and like twitter, I can type in www.myapp.com/username to find the info on that user. I decided that for the initial version I'm just going to use twitter as the login, then later facebook, and lastly the usual sign up. My problem is that it's more than likely that people will have the same usernames in facebook as they do in twitter. So, for example, if I sign in using twitter, and take the 'newuser' ID, it will be an issue when someone with the same username from facebook tries to join.
The OmniAuth gem works by providing a hash of the user info. I'm going to use Mongo, so I can include a twitter and facebook field in the user modle and keep the hashes in there, I'm just a bit stumped as to how to go about creating unique ID's when it's more than likely that both services are going to have people with the same username, or that once the regular login is implemented, someone could sign up and take a username that is already in use on twitter or facebook, preventing those people from signing up with their twitter/facebook accounts.
I'd be really interested to hear how others have approached this.

I'm using a table only for auth keys, it means :user_id, :provider, :key columns, and a seperated User table, :email, :nickname, ...
If the user logged in with his Twitter account, log out, and log in with Google Acc. for instance, then you will have two different accounts, and there's no solution to associate any with an existing account. I suggest you to allow the logged in user to link his currently use user account to another auth provider (you should seperate the user from authentication, and after the first login he should be able to link more auth key to his user account). He logs in to his primary user account (using twitter, for example) and links his user account to his Google account clicking to google icon on auth page.

Related

How Can we configure OAuth 2 to work only for a particular email id?

Suppose I have an application in which I have enabled (google) Oauth2 authentication but I want only a few business people can log in to my application with there specific email id and rest of the people can't. How Can we achieve this using Oauth2?
1.) Lots of people have a Google account and can authenticate with Google
2.) I want Only some of them should be authorized to use your app, which maybe deals with business assets
I suspect your requirement is:
Lots of people have a Google account and can authenticate with Google
Only some of them should be authorized to use your app, which maybe deals with corporate assets
In this case I would proceed something like this:
STEP 1: PREREQUISITE USER SETUP
Get a list of users and perform an Administrator Approval step to create them in your product database, perhaps with Name and Email fields.
STEP 2: INCLUDE THE EMAIL SCOPE DURING LOGINS
In the Google login redirect, use scope='openid email' so that you can identify the user via email after login. Allow users to successfully authenticate.
STEP 3: AFTER LOGIN PROCESS THE ACCESS TOKEN
You will then get then be able to get the user's email address from the access token (though you may have to send it to the Google User Info endpoint).
STEP 4: DENY ACCESS WHEN REQUIRED
If you can't find the email associated to the token in your product user data, present a Forbidden message to the user.
FURTHER INFO
See my User Data Write Up for further details on technical options. Note that I have not actually tested this with Google, but I have used the general approach with a few different systems.

How to log users in with facebook, without having them registered using it initially?

I am adding a Login with Facebook button to my Larvel web app. Users can already register using an email and a password, So what I need to do is to give the users the ability to Login with Facebook, without having to register using Facebook from the beginning. I have already accomplished this, but I facing a security issue.
The authentication flow goes like this once a user cliks the Login with Facebook button:
Redirect users to facebook -> Users enter their email and password -> Facebook returns the user object back -> If the email returned with the user object exists in my database, log the email owner in.
Mostly you have already noticed the problem, but if not, consider this case:
If a user registers with their email in my application, and happens to not have a facebook account associated with that email, then anyone can register a new facebook account with that email, and then just simply log in into my application (Because that email exists in my database!!)
I have been googling this for quite a while now, and it seems like there's no one mentioning this problem, I am assuming this is because I might just be doing it the wrong way!, or maybe it's just done this way! Not really sure.
So, I am seeking guidance, how is this done right?

How can I setup Google Oauth to allow login using an alternate Google account?

I made a members-only site that uses Google oauth2 to authorise users. The site is built with the Laravel framework and Artdarek's oath library.
When the authorization callback comes from Google, I lookup the user record in the DB by email and proceed to the protected page if the record exists, otherwise to a register page.
The problem is some of our members use two Google accounts. One user registered via his primary account (e.ge. a#gmail.com). The next day he returned and mistakenly tried to login with b#gmail.com. Naturally the system showed him the registration page. From that time on each time he visits the site the authentication mechanism sees him using his second (unwanted) set of credentials.
To resolve this one case I instructed him to logout of all accounts (on both sides), clear cookies and start from scratch but this is not a practical solution for all users. In same cases even this measure does not seem to correct the problem.
How can I solve this case? What is the right way to request oauth authentication and get them back from the right account? Can I force Google to ask the user with which account to proceed?
Google will automatically ask the user which account they want on an oauth request if they enable the account chooser.
I have logged into my Google Apps and my Google account, so for me on an oauth request, I get the following prompt:
In order to do the same for your user, they have to click "Stay signed in", but of course this is not advisable for public computers.
Beyond the above, I'm afraid not much can be done. - if they logged in with a#gmail.com at that time, these are the credentials you will receive.
They way I solve this problem is to have a field where the customer can add additional emails, and select one that is primary. I will then inspect against these emails when a request comes in to avoid duplicate user accounts.

Limit which user can sign in using Omniauth-twitter

Im building a simple app and need to add authentication. I was wondering if it was possible within omniauth to limit users that can sign in with twitter by their usernames.
My aim is to only allow a few pre-select people into the backend of this app.
I believe you already have some strategy to manage users signing in with twitter. If not, you might wanna check out this raislcast episode.
Once a user signs in with twitter, twitter will forward you a hash of that user object. You can access it via request.env["omniauth.auth"] and decide if you want to create a user object for a particular username.

Using Facebook Connect in cases where a username or other data is required

I'm working on a site that requires the user have a unique username to use all services on the site. They cannot self-change this username for community fairness.
We would like to allow users the simplicity of registering/logging in using their facebook accounts, but this username requirement is obviously a hurdle.
The only idea I have come up with is after the connect process, send the user to a final step page where they enter a username. The only downside to this is that the user has the ability to navigate away before entering a username, meaning we need to add further layers of checks to several site functions to ensure a user has a username, and prompt for one if not.
Any ideas on how to streamline this during the connect process? Any site examples of similar implementations where auxillary info is required to use some or all site features?
Have you looked at Facebook's registration plugin?
The Registration plugin allows users to easily sign up for your
website with their Facebook account. The plugin is a simple iframe
that you can drop into your page. When logged into Facebook, users see
a form that is pre-filled with their Facebook information where
appropriate.
https://developers.facebook.com/docs/plugins/registration/
The plugin also allows you to add custom fields so you could simply add your username field.
There are a load of advanced features including validation, here's an example in the Facebook documentation that includes the username field and checks to see if it's available
https://developers.facebook.com/docs/plugins/registration/advanced/#async

Resources