Pixelairport's avatar

Connect different socialite ids with one user id

I just watched https://laracasts.com/series/whats-new-in-laravel-5/episodes/9, where socialite is explained. I ask myself, how to avoid problems by connecting social accounts with users. In the video there is only one check... If the user login with github, then check if nickname and email exist in user db and if exist then connect.

My question now is... what is the normal workaround.

For example user login with facebook and did it never before with email (1@1.de), but already logged in with github and email 1@1.de. Will I connect both to one account? I mean normally all the services dont allow to login with an email, which is not confirmed. Or am I wrong? I want to offer later an option that user can also put an password for their account. That means you can login with different social account into your laravel. Is that the right way, or is there a security risk to do it this way. Only by email?

PS: How is it, when user is logged in with one emailaddress (1@1.de) and then hit the route to login with facebook, but there his email is 2@2.de. Does this account should be connected with his 1@1.de account? Or should I logout the user, create a new account and automatically login with 2@2.de account? That would be not clear for the user. What do you think?

0 likes
6 replies
devingray_'s avatar

You are free to do with it as you like.

What I would do is create a relationship

User => HasMany => SocialProvider

SocialProvider will have a table with id, user_id, provider, provider_id for example

Then you can allow them to connect multiple accounts by simply adding additional SocialProviders.

You can still force them to create a password, but adding a nullable constraint to password field in users table and creating a middleware that redirects to a create password page if password is null.

Your socialite callback function would then look something like this.


    public function callback($provider)
    {
        $callback = Socialite::driver('github')->stateless()->user();


        $user = // Find User By Provider and Provider ID or create new user



        Auth::login($user);
        return redirect('/home');
    }



Pixelairport's avatar

Thx. I have already created a extension which has multi entries for one user. A user can have twitch, facebook and google login at the same time. Whats the problem for me to understand... What would you do if user is logged in and his account has the emailadress 1. And then he clicks also login with facebook, where he has another email. Will you create a new account or connect the facebook account to the account in your system with another email.

There could be problems like: You are at your friends computer and want to check something in the app. You login into the app and then click the facebook button. Then the facebook account of your friend is connected to your app.

I know this is not happening often and maybe a problem of big companies... but what is best practise. At the moment i use the email address as value to check if there is an existing account at my app. When user is loggedin and click connect to facebook and there is another email, he also will get a second account at my app. Not sure if that is really the best way.

devingray_'s avatar

Yeah this is something difficult to solve. As facebook and twitter may have two different emails.

What I would do it put a small identifier in the session before the redirect if they are authenticated.

EG


public function redirect()
{
    if (auth->user()) {
     session()->put('user_logged_in_id' , auth()->user()->id);
    }

... then redirect to provider 

}

Then on the callback, try to find that session variable before looking for a user

public function callback($provider)
    {
        $callback = Socialite::driver('github')->stateless()->user();
        
        if (session()->has('user_logged_in_id')) {
                 $user = User::find(session()->get('user_logged_in_id'));
           } else {
               $user = // Find User By Provider and Provider ID or create new user
       }

        Auth::login($user);
        return redirect('/home');
    }

This can handle the current user connecting multiple accounts that may have different emails.

But if they have a login with twitter and then go to another computer and act as a guest to do socialite in facebook, there is no way to cross reference the twitter accounts email :)

martinbean's avatar
Level 80

@pixelairport If security is of concern, then you should only allow people to connect services once they’ve registered and logged in to your application. A user should then only be allowed to say, log in with Facebook if they’ve previously associated that Facebook account with the account they have on your service.

The reason for this is to avoid credential elevation. If I walk into an Apple store and someone’s left themselves logged into Facebook on a MacBook in there, and then I use your website’s “log in with Facebook” functionality, your website’s going to let me log in if there’s an account for that email address even if the user hasn’t connected their Facebook account. Now, I’ve access to both that person’s Facebook account, as well as the account they have on your website without needing their password.

Also, it’s a good idea to connect accounts using the ID on the service and not emails. Reason being, some services may not return the email address at all (from memory, you don’t get the email address from a Twitter account by default unless you request it/you have that permission approved). Also, a user could change their email address on Twitter. Or, they could be like me and use different email addresses for different services. So if you’re just comparing the email address on my Facebook account to the email addresses in your database, you’re not going to find a match even if I’ve actually signed up beforehand.

1 like
Pixelairport's avatar

@martinbean that sound the best solution and i think make the most sense. Maybe i thought to complex instead of thinking easy :) Thanks for your help... You helped me a lot in the last days, while I have problems with all this api, passport, socialite stuff.

1 like
martinbean's avatar

@pixelairport No problem! Glad I was able to help :)

Happy to do my best to answer any questions relating to API and Passport/OAuth. I spent a while working specifically with an API and OAuth, so learned quite a lot about it!

Please or to participate in this conversation.