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

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?

Related

What should happen if a user sign up via social login and then tries to register with same mail?

In my Spring Boot I'd like to have both social login and signup with user and password.
Let's say the user signs-up via Google. After some time, he forgets that he signed-in via Google and tried to register using the same email.
What should happen in this case?
Should I save user info (returned by Google) in a "users" table of my database to prevent the same user to register twice?
Is there an article or something that explains a similar login/registration flow?
you can save all the users(OAuth or signup) in the user table. you can maintain a column by which you will be able to identify them if a user is signed in via OAuth or email. then if a user tries to signup via the same email you can show a message. or you can design your signup process using multiple steps. at first, the user needs to enter her email address, then you can send her an email where she needs to click some link that has some token in the url, if she previously logged in using some oath provider then she will be automatically logged in otherwise she needs to set her password.

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 does Google One-Tap manage my refresh tokens? How does it differ from GAPI?

In the documents of Google One-Tap sign in, it says:
Returning users are signed in automatically, even when they switch devices or platforms, or after their session expires.
Question 1:
But it doesn't say anywhere how it does this? Is the user refresh token saved in the browser's cache? How can it then auto log in a user cross devices?
Question 2: The reason I ask is because I have a setup where I initialize the Google API client for JavaScript ("GAPI"). The GAPI library also automatically logs in a user whenever the client is "initialised" through gapi.client.init().
Now the problem is that after I have added the Google One-Tap code (Or should I say "YOLO code"? : ) my user gets logged in through One-Tap and also through GAPI. I can prevent this by not initializing the GAPI client, but I don't think that's wise, because I thought this whole library is built to manage my refresh tokens etc. Is my understanding correct that One-Tap does exactly the same and in case I only want to Authenticate users I do not need the GAPI client anymore?
Really, which library does a better job at managing my refresh tokens? And how do they differ? I'm clueless...
The way I implemented my login is the following:
Try to login in the user first using gapi.auth2. Maybe the user was previously signed into the site.
If can't login user automatically, then use googleyolo to try to find existing user accounts.
If no existing accounts, then present a signin button for user to signin.
I can give you some code snippet if you need.
To answer your questions.
#1, the credential is stored within the browser/device. If the user has never signed into google in a device, then yolo won't be able to sign in the user.
#2. googleyolo will also login the user, the difference is that it will give the account selector even if there's only one user to select (it will automatically login the user if there's only one). gapi simply sign in the user without showing anything.

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.

User model design when using OAuth

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.

Resources