Providing users the ability to signup / signin with their social accounts is a great idea, it’s fast & secure also.
Laravel has a first-party package called Laravel Socialite which provides an easy way to implement social signin / signup with popular platforms like Facebook, Twitter, Google, LinkedIn, Github, etc.
In this post, I’ll implement Facebook & GitHub only.
So, I’ll install a fresh Laravel project with Jetstream,
laravel new socialite
cd socialite
composer require laravel/jetstream
php artisan jetstream:install livewire
npm install
npm run build
create a Database and setup the .env
file
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=socialite
DB_USERNAME=root
DB_PASSWORD=password
.envThen, Migrate the database.
php artisan migrate
Start the application server, You’ll see a homepage with Login & Register links.
The default login page is fine, But I’ll add two extra links that’s something look like Buttons. So, users can process social login from here.
<a href="{{ url('/auth/github/redirect') }}"
class="py-2 px-4 max-w-md flex justify-center items-center bg-gray-800 hover:bg-gray-700 focus:ring-gray-500 focus:ring-offset-gray-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"
class="bi bi-github mr-2" viewBox="0 0 16 16">
<path
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>
</svg>
Continue with GitHub
</a>
<a href="{{ url('/auth/facebook/redirect') }}"
class="py-2 px-4 max-w-md flex justify-center items-center bg-blue-700 hover:bg-blue-800 focus:ring-blue-500 focus:ring-offset-blue-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"
class="bi bi-facebook mr-2" viewBox="0 0 16 16">
<path
d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951z"/>
</svg>
Continue with Facebook
</a>
login.blade.phpOur UI parts are done.
Install the Laravel Socialite package.
composer require laravel/socialite
Now, we need to add some extra columns in the users’ table. open the users’ migration file and add these extra columns,
$table->string( 'social_id' )->unique()->nullable();
$table->text( 'social_token' )->nullable();
$table->enum( 'login_type', [ 'email', 'github', 'facebook' ] )
->default( 'email' );
PHPMake sure the password column is nullable,
$table->string( 'password' )->nullable();
PHPRun migration
php artisan migrate:fresh
Update $fillable
property in the User model.
protected $fillable = [
'social_id',
'social_token',
'name',
'email',
'password',
'login_type'
];
App/Models/User.phpGitHub
First, go to config/services.php
and add this configuration,
'github' => [
'client_id' => env( 'GITHUB_CLIENT_ID' ),
'client_secret' => env( 'GITHUB_CLIENT_SECRET' ),
'redirect' => 'http://localhost:8000/auth/github/callback',
],
config/services.phpHere, I hard-coded the redirect
URL, but it’s a good idea to manage it via .env
or concatenating with APP_URL
'github' => [
'client_id' => env( 'GITHUB_CLIENT_ID' ),
'client_secret' => env( 'GITHUB_CLIENT_SECRET' ),
'redirect' => env( 'APP_URL' ) . '/auth/github/callback',
],
PHPNext, need to create an OAuth on GitHub.
after creating an OAuth app, you’ll find the Client ID & Client Secret ( you need to generate a client secret) from the app details screen.
Copy the Client ID and Client Secret, put it .env
file
GITHUB_CLIENT_ID=CLIENT_ID_HERE
GITHUB_CLIENT_SECRET=CLIENT_SECRET_HERE
.envCreate a controller called GithubController. I’ll define two methods here, One is for redirect, other for callback.
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Auth;
use Laravel\Socialite\Facades\Socialite;
class GithubController extends Controller {
public function redirect() {
return Socialite::driver( 'github' )->redirect();
}
public function callback() {
$githubUser = Socialite::driver( 'github' )->user();
$user = User::createOrFirst( [
'email' => $githubUser->email
], [
'social_id' => $githubUser->id,
'name' => $githubUser->name,
'social_token' => $githubUser->token,
'login_type' => 'github'
] );
// if user is already existed, we need to check login_type.
if ( $user->login_type !== 'github' ) {
return redirect( 'login' )
->withErrors( [ "email" =>
"Your email already used to manage another account !" ]
);
}
Auth::login( $user );
return redirect( '/dashboard' );
}
}
GithubController.phpDefine two routes, One for redirect & other for callback,
Route::prefix( '/auth' )->group( function () {
Route::get( '/github/redirect', [ GithubController::class, 'redirect' ] );
Route::get( '/github/callback', [ GithubController::class, 'callback' ] );
} );
web.phpThe solution is the same as Github.
'facebook' => [
'client_id' => env( 'FACEBOOK_CLIENT_ID' ),
'client_secret' => env( 'FACEBOOK_CLIENT_SECRET' ),
'redirect' => env( 'APP_URL' ) . '/auth/facebook/callback'
],
config/services.phpGo to the Facebook developers’ website and create an app.
create a test app inside the newly created app.
Inside the test app, Under App Settings | Basic, you’ll find the App ID & App secret
Copy & put them in .env
file
FACEBOOK_CLIENT_ID=APP_ID_HERE
FACEBOOK_CLIENT_SECRET=APP_SECRET_HERE
.envUnder App Settings | Advanced, you need to insert a callback URL in the Share Redirect Domain Allow List.
At the end, define routes and create a controller.
Route::prefix( '/auth' )->group( function () {
Route::get( '/github/redirect', [ GithubController::class, 'redirect' ] );
Route::get( '/github/callback', [ GithubController::class, 'callback' ] );
Route::get( '/facebook/redirect', [ FacebookController::class, 'redirect' ] );
Route::get( '/facebook/callback', [ FacebookController::class, 'callback' ] );
} );
web.php<?php
namespace App\Http\Controllers;
use App\Models\User;
use Auth;
use Laravel\Socialite\Facades\Socialite;
class FacebookController extends Controller {
public function redirect() {
return Socialite::driver( 'facebook' )->redirect();
}
public function callback() {
$facebookUser = Socialite::driver( 'facebook' )->user();
$user = User::createOrFirst( [
'email' => $facebookUser->email,
], [
'social_id' => $facebookUser->id,
'name' => $facebookUser->name,
'social_token' => $facebookUser->token,
'login_type' => 'facebook'
] );
if ( $user->login_type !== 'facebook' ) {
return redirect( 'login' )
->withErrors( [ "email" =>
"Your email already used to manage another account !"
] );
}
Auth::login( $user );
return redirect( '/dashboard' );
}
}
FacebookController.phpThats it!
Email Login
In this example, I’m using Jetstream and need to update the authentication process. The authentication portions of Jetstream are powered by Laravel Fortify
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Laravel\Fortify\Fortify;
/**
* Bootstrap any application services.
*/
public function boot(): void {
// ...
Fortify::authenticateUsing( function ( Request $request ) {
$user = User::where( 'email', $request->email )->first();
if ( $user && Hash::check( $request->password, $user->password )
&& $user->login_type === 'email' ) {
return $user;
}
} );
}
JetstreamServiceProvider.phpYou’ll find the complete source code here.
Thanks.
Leave a Comment