Search code examples
phplaravellaravel-5.1laravel-socialite

Laravel 5.1 & Socialite - How to connect Facebook/Twitter details to currently authenticated user


I've implemented Socialite fine and works for new users or users that have the same Facebook email address as the email address in my apps database.

However, some users will have a different Facebook email account to the account they use in my app. I would like to allow users to connect their facebook profile to their app account when they are logged in.

Here are my routes:

Route::get('login/{provider}', 'Auth\AuthController@redirectToProvider');
Route::get('login/{provider}/callback', 'Auth\AuthController@handleProviderCallback');

redirectToProvider code:

public function redirectToProvider($provider)
{
    return Socialite::driver($provider)->redirect();
}

Below is my current code that handles the socialite user creation/update:

public function handleProviderCallback($provider)
    {
        $user = Socialite::driver($provider)->user();

        $user_query = User::where('email', $user->email)
            ->orWhere('oauth_facebook_id', $user->id)
            ->orWhere('oauth_twitter_id', $user->id)
            ->get();

        if($user_query->count() > 0) {

            $the_user = $user_query->first();

            if($provider === 'facebook') {
                $the_user->oauth_facebook_id = $user->id;
            }

            if($provider === 'twitter') {
                $the_user->oauth_twitter_id = $user->id;
            }

            $the_user->avatar = $user->avatar;

            $the_user->save();

            \Auth::login($the_user, true);

            return redirect('/dashboard');
        }

        $new_user = User::create([
            'name' => $user->name,
            'email' => $user->email,
            'oauth_facebook_id' => $provider === 'facebook' ? $user->id : NULL,
            'oauth_twitter_id' => $provider === 'twitter' ? $user->id : NULL,
            'avatar' => $user->avatar,
            'confirmed' => true,
            'gender' => $user->user['gender'],
        ]);

        \Auth::login($new_user, true);

        flash()->success('Success!', 'Your account has been created using your '.ucfirst($provider).' details!');
        return redirect('/dashboard');
    }

What would be the best way to link the returned details with the current authenticated user?

Thanks in advance :)


Solution

  • Just check if the user is logged in and then update that user's oauth_{provider}_id with the returned data from the provider ($userData->id).

    Otherwise, create a new user with the returned data.

    Something like this:

    public function handleProviderCallback($provider)
    {
        $userData = Socialite::driver($provider)->user();
    
        if(Auth::check()) {
    
            $user = User::find(Auth::user()->id);
    
            if($provider === 'facebook') {
                $user->oauth_facebook_id = $userData->id;
            }
    
            if($provider === 'twitter') {
                $user->oauth_twitter_id = $userData->id;
            }
    
            $user->save();
    
        } else {
    
            $new_user = User::create([
                'name' => $userData->name,
                'email' => $userData->email,
                'oauth_facebook_id' => $provider === 'facebook' ? $userData->id : NULL,
                'oauth_twitter_id' => $provider === 'twitter' ? $userData->id : NULL,
                'avatar' => $userData->avatar,
                'confirmed' => true,
                'gender' => $userData->user['gender'],
            ]);
    
            \Auth::login($new_user, true);
    
            flash()->success('Success!', 'Your account has been created using your '.ucfirst($provider).' details!');
    
        }
    
        return redirect('/dashboard');
    }