TuTaMixx
2 years ago
149
5
Laravel

Socialite Connect Multiple Social Accounts with Different Emails

Posted 2 years ago by TuTaMixx

Hi all,

I would like to create a multiple social login app on Laravel with Socialite package. I can connect with social accounts.(Facebook, Twitter, Google). They are working well. Also if the social accounts have same e-mail address then it will link them each other.

The thing that I would like to do is linking the accounts that do not have same e-mail address.

There will be buttons on the profile page;

Connect with Facebook
Connect with Twitter
Connect with Google

Authenticated user will click one of them and can link his/her social account.

I could not figure out how to do.

This is my login controller;

    <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

use App\SocialAccount;
use App\User;
use Carbon\Carbon;
use Socialite;
use Laravel\Socialite\Contracts\User as ProviderUser;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest', ['except' => 'logout']);
    }

    public function showLoginForm()
    {
        if(!session()->has('url.intended')) {
            session()->put('url.intended', url()->previous());
        }

        return view('auth.login');
    }

    /**
     * Redirect the user to the provider authentication page.
     *
     * @return Response
     */
    public function redirectToProvider($provider)
    {
        if ($provider == 'twitter' || $provider == 'google') {
            return Socialite::driver($provider)->redirect();
        }
        else
        {
            return Socialite::driver($provider)->fields([
                'name', 'email', 'gender', 'birthday'
            ])->scopes([
                'email', 'user_birthday'
            ])->redirect();
        }
    }

    /**
     * Obtain the user information from provider.
     *
     * @return Response
     */
    public function handleProviderCallback($provider)
    {
        if(!session()->has('url.intended')) {
            session()->put('url.intended', url()->previous());
        }

        if ($provider == 'twitter' || $provider == 'google') {
            $user = $this->findOrCreateUser(Socialite::driver($provider)->user(), $provider);
            auth()->login($user, true);
        }
        else{
             $user = $this->findOrCreateUser(Socialite::driver($provider)->fields([
            'name', 'email', 'gender', 'birthday'
        ])->user(), $provider);
        auth()->login($user, true);
        }
        
        return redirect()->intended('/');
    }

    public function findOrCreateUser(ProviderUser $providerUser, $provider)
    {
        $account = SocialAccount::where('provider', '=', $provider)
            ->where('provider_user_id', '=', $providerUser->getId())
            ->first();

        if ($account) 
        {
            return $account->user;
        } 
        else 
        {
            $account = new SocialAccount([
                'provider_user_id' => $providerUser->getId(),
                'provider' => $provider,
                'username' => $providerUser->getNickname()
            ]);

            $user = User::where('email', '=', $providerUser->getEmail())->first();

            if (!$user) 
            {
                $user = User::create([
                    'email' => $providerUser->getEmail(),
                    'name' => $providerUser->getName(),
                    'avatar' => $providerUser->getAvatar(),
                    //'gender' => $providerUser->user['gender'],
                    //'birthday' => Carbon::parse($providerUser->user['birthday'])->format('Y-m-d'),
                    //'gender' => $providerUser['user']['gender'],
                ]);
            }

            $account->user()->associate($user);
            $account->save();

            return $user;
        }

    }
}

Thanks in advance.

Please sign in or create an account to participate in this conversation.