Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OmniAuth: Guarding against multiple accounts for the same user

I have a couple of Rails apps I'm looking to integrate with OmniAuth, but there is a conceptual problem I'm having with it that I'd like to figure out first. Consider the following scenario:

  1. Your application, Foo, supports OmniAuth logins via Twitter and Facebook.
  2. Joe comes to your site and logs in via his Twitter account. This creates a new user on Foo and associates it with this new Twitter authorization.
  3. Joe logs out of Foo, and forgets about the site for six months.
  4. Joe returns to Foo, not remembering that he has previously logged in with Twitter.
  5. Joe logs in with Facebook. Since he is not already logged in via his original Twitter authorization, there is no way to detect that he is, in fact, the same Joe, and a new account is created.
  6. Joe discovers his old account, and is now frustrated that his older content is tied to this old account, and that he can't log in with Twitter and Facebook interchangeably.

Since Twitter does not supply Foo with an email address, there is no universal identifier to use for detecting that the two Joes are the same Joe. You could decide to support only providers who give you the user's email address, but this doesn't help if the user has registered with different email addresses on different providers.

The only other solution I can think of is to give the user some way of merging two existing accounts. That's a big headache compared to the relative ease of everything else when using OmniAuth. If this is the only solution, has anyone come across a guide/tutorial showing an example of how this might be done? I'm surprised this issue hasn't gotten more attention given the popularity of OmniAuth.

Thanks!

like image 872
Jimmy Avatar asked Jan 10 '11 06:01

Jimmy


4 Answers

Your gut feeling is correct. You'll have to provide a merge tool for your user... or you can ignore the problem.

like image 94
Mark Amerine Turner Avatar answered Nov 15 '22 12:11

Mark Amerine Turner


I know this is an old question but thought I would answer with what I have recently done on a project anyway, just for reference.

Full disclosure: I didn't come up with this, I stole it from somebody else on the web. There's a good write up on the Omniauth wiki.

I never found a nice way to automagically link Facebook/Twitter/etc accounts but instead made it so the user can link multiple accounts once they have logged in with the first one.

This is the scenario:

  • The user logs in with e.g. Facebook
  • They have a profile page which lists the social networks they have attached to the account, and an option to link each type to the account
    • e.g "Facebook Linked | Link Twitter | Link Google"
  • "Link Twitter" for example links to the same omniauth action a user would use to log in Twitter
  • in the callback handler, check to see if the user is logged in
    • if they are, store the provider and uid in a separate record for the user
    • otherwise, log them in as usual

Instead of storing the provider and uid on the user model, the model would then be a user can have many social network identities.

Again, sorry for raising the dead, but Abe Petrillo's comment in reply to the accepted answer made me think another view might be useful.

like image 22
Scott Payne Avatar answered Nov 15 '22 12:11

Scott Payne


I also came across this problem today. I think I will handle it the following way:

I will ask the user for their email and a password when signing up, just like in a traditional authentication setup, where I try to get the email from the OmniAuth Service the user has chosen (FB, Twitter,...). So they only have to supply the email if it is not supplied by the auth provider. Then, if the user signs in later with the same provider they used for sign up, they will be logged in straight away. This will probably happen in 99% of all cases.

However, having the email and password of the user I can also handle all kind of cases that could occur (including the one you describe):

  • The original authentication provider is down or the user deleted their authentication provider account -> Solution: The user can login the traditional way, using their email and password. (Note, that this is an important case that I haven't seen mentioned anywhere on the net yet. People seem to assume that FB, Twitter, etc will be there forever, will never be down and users will never quit their accounts with those services. By not storing the users pw and email you will loose all your user accounts which were generated by a provider if one of these cases ocurrs, as you can't map them to users anymore. To me that is an unacceptable dependency on an external service.)

  • The user logs in later with a different authentication provider (this is your case) -> Solution: Try to map the user to an existing account using their email, if that fails, display the signup form with a button/link "I have already an account, please log me in" (or similar ;-). If they click that, they have to supply their email and password. Then, if they authenticate successfully, you can simply add that provider to the existing user record, and next time they are logged in straight away, just like with the provider they originally used for signup...

Maybe there are other cases that could occur. Any Feedback?

like image 20
Nico Avatar answered Nov 15 '22 12:11

Nico


I noticed that Stack Overflow appears to try and overcome this issue, to some extent, by storing the user's authentication preference in a cookie, and automagically logging you in when you return to the sign-in page.

Whilst it still doesn't provide a complete solution to this problem, it probably helps to minimise fallout.

like image 2
theTRON Avatar answered Nov 15 '22 12:11

theTRON