This is part two of the Laravel 5.2 socialite auth tutorial. In the first part we installed socialite plugin, prepared configuration, made a service which will handle creating users with social accounts and made it work with facebook.
Configuring Twitter App
This time we will try to add an option to login with twitter.
Like with facebook, you need to use twitter panel for developers where you need to create the app. Go to the Twitter Apps page, and click Create New App.
Enter the application name and description. For website use http://placeholder.com
or any other fully qualified url that can pass validation. For production you can put your real website address. For development we will use placeholder address.
Configuring Socialite
Click on the Keys and Access Tokens tab. With this we can configure Socialite.
Copy Consumer Key (API Key) to client_id
, Consumer Secret (API Secret) to client_secret
. For redirect we will use already built route but with additional parameter so we will be able to make distinction between different providers (in this case facebook and twitter). In the redirect
field enter http://localhost:8000/callback/twitter
.
'twitter' => [
'client_id' => 'jvVgZoMJFDGF0nuSRFzrE4jO3',
'client_secret' => 'onPJd84dU1ZrHgsGmWCFBI4iv5octmWDLQooJ1TZix1T34ttjf',
'redirect' => 'http://localhost:8000/callback/twitter',
],
Using more than one provider
Currently we don't have the route we defined above in our app, so let's make it. Change callback route definition to this:
Route::get('/callback/{provider}', 'SocialAuthController@callback');
And callback
method in SocialAuthController
needs to use that new parameter to tell socialite what driver to use.
public function callback(SocialAccountService $service, $provider)
{
// Important change from previous post is that I'm now passing
// whole driver, not only the user. So no more ->user() part
$user = $service->createOrGetUser(Socialite::driver($provider));
auth()->login($user);
return redirect()->to('/home');
}
Small change to the SocialAccountService
. It will receive concrete provider, so we dont need to pass $provider
parameter to the createOrGetUser
method. We will use class name of the provider to differentiate between them before we save SocialAccount
to the database.
<?php
namespace App;
use Laravel\Socialite\Contracts\Provider;
class SocialAccountService
{
public function createOrGetUser(Provider $provider)
{
$providerUser = $provider->user();
$providerName = class_basename($provider);
$account = SocialAccount::whereProvider($providerName)
->whereProviderUserId($providerUser->getId())
->first();
if ($account) {
return $account->user;
} else {
$account = new SocialAccount([
'provider_user_id' => $providerUser->getId(),
'provider' => $providerName
]);
$user = User::whereEmail($providerUser->getEmail())->first();
if (!$user) {
$user = User::create([
'email' => $providerUser->getEmail(),
'name' => $providerUser->getName(),
]);
}
$account->user()->associate($user);
$account->save();
return $user;
}
}
}
Now we don't have a valid callback for facebook, lets change that:
'facebook' => [
'client_id' => '690344774435367',
'client_secret' => 'ebc50d3fd1d2f7286e02d247e5751ef4',
'redirect' => 'http://localhost:8000/callback/facebook',
],
To allow users to choose with what network they want to login, we need to make distinction between redirects. Similar to the callback change, we will change routes.php
and SocialAuthController
's redirect
method.
Route::get('/redirect/{provider}', 'SocialAuthController@redirect');
Controller:
public function redirect($provider)
{
return Socialite::driver($provider)->redirect();
}
Now we will add Twitter Login link and change FB Login link to use new route.
<p>
<a href="redirect/facebook">FB Login</a>
<a href="redirect/twitter">Twitter Login</a>
</p>
And that is all. Click on the Twitter Login and you will be redirected back and logged in.
Next useful thing that comes to my mind is how to merge two or more social accounts into one.
Update: I added a comment in one of the code snippets to make changes from the previous post more visible.