Posted by Arjun on Tuesday 5th June 2018

Laravel 5.6 Socialite Bitbucket Login

Social Logins Laravel 5.6 Socialite BitBucket Login

In this tutorial, we’re going to explain how to integrate Bitbucket login in Laravel based application using Socialite. The Socialite is Laravel's official package, which is making is easy to authenticate with external services with OAuth providers.

Create Project

Create a brand new Laravel 5.6 project with Composer create-project command:

$ composer create-project laravel/laravel arjunphp-bitbucket-login 5.6 --prefer-dist

Database connection settings

After creating project open .env file and update your database credentials:

...
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=arjunphp_bitbucket_login
DB_USERNAME=root
DB_PASSWORD=mysql
...

Next step, would be, go to the project root and open the terminal and type the following command. It will create the two tables, which is by default ships by Laravel 5.6

$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table

You might get following error :

PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes")

to fix this, all you have to do is to edit your AppServiceProvider.php file and add to the boot method a default string length:

...
use Illuminate\Support\Facades\Schema;

....
function boot()
{
    Schema::defaultStringLength(191);
}
...

Lets add two new columns called provider_id, provder to the users table, create a migration file with below commnad

$php artisan make:migration add_socail_provider_columns_to_users_table
Created Migration: 2018_06_05_064007_add_socail_provider_columns_to_users_table

Open create migration file and update it as shown below

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddSocailProviderColumnsToUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function($table) {
            $table->string('provider_id');
            $table->string('provider');
            $table->string('email')->nullable()->change();
            $table->string('password')->nullable()->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function($table) {
            $table->dropColumn('provider_id');
            $table->dropColumn('provider');
        });
    }
}

NOTE: Changing columns for table "users" requires Doctrine DBAL; so install "doctrine/dbal" with composer

$ composer require doctrine/dbal

Again run the php artisan migrate command from the project root. It will add new columns to the user table and it will modify email and password default values to null.

Now update your user model fillable array as shown below, with new columns

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'provider','provider_id'
    ];

Installing Socialite

To get started with Socialite, use Composer to add the package to your project’s dependencies:

$ composer require laravel/socialite

Log in to your LinkedIn developer account and create an application and grab the client id and client secret. Open your config/services.php configuration file and place credential inside it as shown below.
(In real app place config values in the .env file, it is a good practice).

  'bitbucket' => [
    'client_id' => 'xxxx',
    'client_secret' => 'xxx',
    'redirect' => 'http://localhost:8000/auth/callback/bitbucket',
  ],

so let's define callback and redirect routes in routes/web.php file:

Route::get('auth/callback/{provider}', '[email protected]');
Route::get('auth/redirect/{provider}', '[email protected]');

Create a controller called SocialAuthController with following artisan command

$php artisan make:controller SocialAuthController
Controller created successfully.

Now update your controller with below code:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Socialite;
use Laravel\Socialite\Contracts\Provider;
use App\User;
use Auth;

class SocialAuthController extends Controller
{
    
    public function callback($provider)
    {
     
        $user = $this->createOrGetUser(Socialite::driver($provider));
     
        auth()->login($user);
     
        return redirect()->to('/');
    }

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

    private function createOrGetUser(Provider $provider)
    {
 
        $providerUser = $provider->user();

        $providerName = class_basename($provider);
 
        $user = User::whereProvider($providerName)
            ->whereProviderId($providerUser->getId())
            ->first();
 
        if (!$user) {
            $user = User::create([
                'email' => $providerUser->getEmail(),
                'name' => $providerUser->getName(),
                'provider_id' => $providerUser->getId(),
                'provider' => $providerName
            ]);
        }
        
        return $user;
    }

    public function logout(Request $request) {
        Auth::logout();
        return redirect('/');
    }
}

Now update view file welcome.blade with below code:

    <div class="flex-center position-ref full-height">
            @auth
             <p>welcome {{ Auth::user()->name }}</br>
             <a href="{{ url('/auth/logout') }}">Logout</a></p>
            @else
             <a href="{{ url('auth/redirect/bitbucket') }}">bitbucket Login</a>
            @endauth
        </div>

That's it, now start the application with php artisan serve, and access your application http://localhost:8000.