Authenticate account if email exists after facebook auth - ruby-on-rails

Users can register an account on my site via the default authentication method that requires a username, email and password.
To allow users to login via facebook, I am using the facebook gem with Omniauth gem.
Existing guides shows me how to authenticate the users up to the point where they can confirm their details ("is your first and last name correct?") before successfully tying the uid and provider to the user record.
However, it does not check if the email is the same.
Does anyone know how to check if the email is the same and if it is, request the user to provide their password to the account already registered on my site either on the same screen for confirming user details or a new screen with just a password field and a message indicating that he needs to confirm he owns an account on my site with the same email facebook provides.
Should this be done on the model or controller layer? How would you go about doing this?

Related

How can users sign up to a Cognio User Pool through Facebook when email attribute is required but Facebook doesn't provide it?

My AWS Cognito Pool has email as a required attribute. All users who sign up to my app have been required to provide their email.
I've recently added Facebook as an Identity Provider to my user pool.
The problem is that Facebook doesn't always provide an email, and in those cases, Cognito will redirect new users to an error page saying "Email is Required".
I want to prompt the user to enter his/her email and then continue the sign up process, rather than just ending it with an error. Is there any way to do this?
This simply is not currently possible with Cognito User Pools.
I've hit the same example when working with clients, even when consenting to the appropriate scopes, Facebook will not provide it in the OpenID token.
I suspect though that the email is retrievable via the API following this, so you may have some luck with a Cognito User Pools trigger to go retrieve the email and stuff it in post-authentication if it's missing.
Otherwise there's not a lot you can do other than making email address optional and then designing customer experience around this.
If you have set 'Email' in the Facebook token scope, Facebook will provide the email address if it has one. However, Facebook itself doesn't always have an email address for a user
https://developers.facebook.com/docs/facebook-login/permissions/#reference-email
Note, even if you request the email permission it is not guaranteed
you will get an email address. For example, if someone signed up for
Facebook with a phone number instead of an email address, the email
field may be empty.
In this case I think you either have to live with the current Cognito behaviour, or make email optional, but effectively enforce it yourself with a Cognito Post-Authentication Lambda trigger

iOS App - Users table/model (to support both manual signup and Auth0)

I am creating an iOS app, and am working through the signup/login flow trying to understand how to structure my user model.
I want to allow users to sign up via facebook/twitter as well as using a standalone email/password if they don't want to authenticate through a service.
I am using auth0 to handle service authentication.
What is the standard process of storing / keeping track of my users if some are signing up through email/password, and others are simply authenticating through Auth0.
This is what I've come to so far:
My user model will contain the following properties at a minimum:
_id
name
email
password (will be blank for authenticated users)
auth0_id (will be blank for non-authenticated users)
How I will validate a user on login:
If a user who signs up manually (email/password) wants to log back in, I will check their email exists in my users table and then run a match on their password, if a match - return the user object.
If a user who authenticates through a service wants to log back in, I will make the call to Auth0, check their auth0_id exists in my users table, and then run return the user object.
Does this pose any security issues?
Comments/suggestions welcome!
I recommend decoupling your user and auth0 models from each other. For example:
User schema:
_id
name
email
password
Auth0 schema:
_id
auth0_id
user_id
I also recommend requiring a password on the user schema, and generating a strong password for users that register through Auth0. This will ensure that all users have a "standard" user account regardless of Auth0 and their continuing to have those services in the future (ex: the user deletes their Facebook account but continues to use your service – all they have to do is run through your "forgot password" flow).
Then have a standard login flow and an Auth0 login flow – the latter is the standard Auth0 flow, you check that the Auth0 ID exists and return the joined user record.
Did you consider using the email/password functionallity that is built-in in Auth0? That way you don't have to keep two different logics.

Correct way for sign up with Twitter Using Devise and Omniauth?

I am creating a rails app that requires sign up with twitter feature.And my application is based on email marketing service.Various types of email we will send user for the updates.
My concern here is that,twitter does not provide the email ID in response while authenticating a user via twitter API.
And now if I am creating that user in my database and allowing him to sign up by skipping some validation (Like email field is required). Then what should happen in the situation when my application will try to send the email to users.And this twitter user is not having email ID.
It will just skipped.
Is there any proper flow that I can use,so my app will work in correct flow.
Thanks!
Twitter doesn´t give you the email via API.
This works if you are using omniauth-facebook gem for example, but twitter doesn´t offer you the email - you have to create a workaround.
For example ask the user in a second step to fill in his/her email adress.

How to combine local and Facebook users in iOS app

I want to give the opportunity for a user of an app to register/login with Facebook or by creating an account. I know that I can get the user's Facebook account email address, and their first and last names. That's basically the only information for creating a 'local' app account, apart from a password. How can I make sure that if that person logs in to Facebook on another device, that their two devices are linked to the same 'local' account? (i.e if they choose to sign in with Facebook with 2 devices, I only want one local account to be created on my server for that user).
Ideally, I want the login schemes for both to be identical. So if that user logs in with Facebook, I can check (securely) that the FB account is linked to a 'local' account, and automatically log that device in without making the user type in a password. Is this possible?
Edit: The 'local' users will be stored in a database on my server, and the front end will be done in Python running alongside the API for the app. Note that 'local' is just referring to the fact that it uses my app web service rather than an external social network.
You can do that within your users database as per below:
assuming you store the user data in a table named userinfo, this table should contain user e-mail, first name, etc..
Add another column in this table named fbemail.
If users signs in using web service, his email will be saved in the email field & the fbemail should be null, if signs in using FB, then both email & fbemail should be the extracted email.
when the user uses FB login, check the fbemail field, if not found, then this is a new user, add his data, if not, then this is a returning user, no need to add his data.
Option 1.
You can identify your Facebook user by his Facebook User ID. If he logs in using Facebook on other device you know it cause he sends you his Facebook User ID in the authentication process. He also sends you Facebook access token which you validate contacting Facebook to see if it is correct. Using this approach you have to have a different authentication scheme for Facebook user and "normal", email user.
Option 2.
To have the same login scheme you can use Facebook to get user email and prepend it in the email text field in your registration screen. The user would need to additionally provide a password. This means that you are not really doing a Login with Facebook, but use Facebook to obtain an email (and any additional information) so the user does not have to type it.
This is an old post but still very valid. You are correct, anybody who has your FB email could potentially access your server rest-api and log into it. To access a backend service you will need to use as password the FB access token generated during the FB log-in. This is stored in the device keychain and can be retrieved as:
NSString *accessToken = [[FBSDKAccessToken currentAccessToken] tokenString];
NSString *userID = [[FBSDKAccessToken currentAccessToken] userID];
The topic of using a FB authentication system in parallel to a custom login/registration system is covered in this FB guide: Using Facebook Login with Existing Login Systems.
In sum, different scenarios need to be addressed:
A person signs up for your app using their email and password, but later they want to use Facebook Login to obtain data from their Facebook account, to post to their timeline, or just to use to log in with in future.
A person signs up for the app using their email and password, but later chooses to log in with Facebook separately. This guide assumes that the email supplied first and the primary email associated with their Facebook account are the same.
A person signs up for the app using Facebook Login and later wants to log in to this account using an email address and password.
The guide recommends using two different tables for the FB log-in and the custom login.

Linking new users signed in via Facebook connect to existing accounts

I have recently implemented login to my via facebook connect. So now users have 2 ways of logging in to the site. The old way of registering an account and the new way (facebook connect).
One thing I would like to do is link a new facebook connect user account to existing accounts if they logged in the old way.
Has anyone had any success doing this?
Very good question I think and lots of people will benefit from an answer.
What you need to remember is that accounts are only linked so long as they are authorised to be linked through Facebook. What you should do is maintain a second table of linked accounts in your database so that you know who is who and if they are linked with Facebook.
You should read this integration comment, it provides a lot of useful information.
http://crazyviraj.blogspot.com/2010/01/test-cases-for-basic-facebook-connect.html
It doesn't really say how to do things, but it makes sure you tick all the boxes of what you should be doing.
ie:
Sign Up should fail if the user denies
permission to the app (category: sign
up)
Since we need access to an email
address, Sign Up should fail if the
user provides publish permission but
denies email permission (category:
sign up)
If the user provides an email address
that already exists in your system,
fail Sign Up. Make sure no YouFace
backend tables are modified (category:
sign up, 1:1 mapping) PS - when this
happens, I didn't find a way for you
to de-authorize YouFace on the
Facebook user's behalf. The user must
manually do this if they wish you use
the same account but provide a
different email address.
Accounts created using Facebook
Connect should not be able to login
using YouFace's default email/password
login system (category: sign in,
account security). PS: Since YouFace
accounts require a password and those
created using Facebook Connect don't,
make sure to insert a random password
hash into your table to avoid silly
errors
Accounts created using YouFace should
be able to sign in without requiring
to be signed into Facebook, even if
when a link to a Facebook accounts
exists (category: sign in)
Any many more
You should be asking for permanent access through fb connect authentication. Once you've done that, you'll get a token which gives your permission to access someone's Facebook information, and that token will not expire unless the user explicitly removes you from the permission list or changes his/her password.
Once you have the token, associate that token with the user / create a new field in your user table to store it.
To associate the user with a Facebook account without the user logging in, you can try to match by email. It's not 100% accurate but it's pretty good. Facebook doesn't give you email addresses in text form but you can get email hashes from FQL. Since you already know user email addresses, you can calculate the hash for all of your user emails and search through your user base for matches every time a new Facebook Connect user signs up.

Resources