The purpose of this document is to describe the process of implementing the Laravel Socialite Package to achieve social media login via the mainstream social media as well as Google and Apple.

Before we start implementing the social logins we need to install the Laravel socialite plugin like so:

composer require laravel/socialite

We then need to register two routes. One of them will send the log in request to the social media provider and one will be for the callback.

You can implement them like so:

/* =========== Social Log In Route ============= */
Route::get('/redirect/{service}', 'SocialAuthController@redirect');
Route::get('/callback/{service}', 'SocialAuthController@callback');
/* =========== Social Log In Route: END========== */

You will notice that service is a wildcard.

We used this technique so that we don’t have to create a new redirect-callback pair for each provider and also because the credentials are changing every time but the logic remains pretty much the same.

The redirect and callback functions look like this:

Redirect:

    /**
     * Redirect to login service, i.e facebook, google
     *
     * @param mixed $service
     * @return
     */
    public function redirect($service)
    {
        return Socialite::driver($service)->redirect();
    }

Callback:

 /**
     * Callback from login service, i.e facebook, google
     *
     * @param mixed $service
     * @return
     */
    public function callback($service)
    {
        if ($service == 'twitter') {
            //twitter-instagram doesn't support stateless
            $user = Socialite::driver($service)->user();
        } else {
            $user = Socialite::driver($service)->stateless()->user();
        }
    }

You will notice that twitter is handled in a special case but this will be explained further down, at the Twitter section. The $user variable represents the user data returning from each social media api. You can then proceed implementing any type of logic you want using that data or you can initially dump the object returned to the available user data.

Now that all the foundation has been set up, implementing each social media provider is relatively simple.

Instructions to Implement Facebook Log in

  1. Add the facebook configuration to services.php and create your .env variables: 
2.      'facebook' => [
3.          'client_id' => env('FACEBOOK_CLIENT_ID'),
4.          'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
5.          'redirect' => env('FACEBOOK_CALLBACK_URL'),
    ],
  1. You can then go to facebook developers site, set up an app and copy the credentials into your .env: https://developers.facebook.com/
  2. That’s it. You can now test the functionality by visiting /redirect/facebook

Instructions to Implement Google Log in

  1. Add the google configuration to services.php and create your .env variables: 
2.      'google' => [
3.          'client_id' => env('GOOGLE_CLIENT_ID'),
4.          'client_secret' => env('GOOGLE_CLIENT_SECRET'),
5.          'redirect' => env('GOOGLE_CALLBACK_URL'),
    ],
  1. You can then go to google developers site, set up an app and copy the credentials into your .env: https://console.developers.google.com
  2. That’s it. You can now test the functionality by visiting /redirect/google

Instructions to Implement LinkedIn Log in

  1. Add the linkedin configuration to services.php and create your .env variables: 
2.      'linkedin' => [
3.          'client_id' => env('LINKEDIN_CLIENT_ID'),
4.          'client_secret' => env('LINKEDIN_CLIENT_SECRET'),
5.          'redirect' => env('LINKEDIN_CALLBACK_URL'),
    ],
  1. You can then go to linkedin developers site, set up an app and copy the credentials into your .env: https://www.linkedin.com/developers/
  2. That’s it. You can now test the functionality by visiting /redirect/linkedin

Instructions to Implement Twitter Log in

  1. Add the twitter configuration to services.php and create your .env variables: 
2.      'twitter' => [
3.          'client_id' => env('TWITTER_CLIENT_ID'),
4.          'client_secret' => env('TWITTER_CLIENT_SECRET'),
5.          'redirect' => env('TWITTER_CALLBACK_URL'),
    ],
  1. You can then go to twitter developers site, set up an app and copy the credentials into your .env: https://developer.twitter.com/
  2. That’s it. You can now test the functionality by visiting /redirect/twitter
  3. Twitter set up has an extra step. When you get the user data back you will notice that his email is not present. For most applications you will need the user’s email.
    Not to worry. From the twitter developer console, go to your app, open the app setting and check the option that allows the app to share the user’s email.
  4. Now revisit /redirect/twitter and make sure that the user returned contains the email field

Redirecting back to the URL that the social login started from:

  1. In the redirect function, before the redirect happens, we save the url of the previous page in a session variable like so:
2.       /**
3.       * Redirect to login service, i.e facebook, google
4.       *
5.       * @param mixed $service
6.       * @return
7.       */
8.      public function redirect($service)
9.      {
10.        session(['socialite_link_previous' => url()->previous()]);
11. 
12.        return Socialite::driver($service)->redirect();
    }
  1. In the callback function, we check if the session variable exists, and if it does we redirect back to it:
14.     /**
15.     * Callback from login service, i.e facebook, google
16.     *
17.     * @param mixed $service
18.     * @return
19.     */
20.    public function callback($service)
21.    {
22.        if ($service == 'twitter') {
23.            //twitter-instagram doesn't support stateless
24.            $user = Socialite::driver($service)->user();
25.        } else {
26.            $user = Socialite::driver($service)->stateless()->user();
27.        }
28. 
29.       //Add your logic here..
30. 
31.        if (session('socialite_link_previous')) {
32.            return redirect(session('socialite_link_previous'));
33.        }
34. 
35.        return redirect()->route('A backup route in case the session variable doesn't exist');
    }

During the implementation of The Socialite package we tried two more providers which were Instagram and Apple login. The problem with instagram was that it doesn’t return the user’s email and it gives no option on the Instagram app side to include it. For our specific application we did need the user’s email so we decided not to pursue instagram login any further. We also tried Log in with Apple but we noticed that you have to be an Apple Developer to create an app and get the credentials.