Ngoài xác thực dựa trên biểu mẫu điển hình, Laravel cũng cung cấp một cách đơn giản và thuận tiện để sử dụng Laravel Socialite để xác thực với các nhà cung cấp OAuth. Socialite hiện hỗ trợ xác thực qua Facebook, Twitter, LinkedIn, Google, GitHub, GitLab và Bitbucket.

Trong bài viết này, tôi sẽ hướng dẫn các bạn cách sử dụng Laravel Socialite để thực hiện đăng nhập qua Google.

Cài đặt Laravel

Đầu tiên, chúng ta cần tạo một dự án Laravel mới, sử dụng lệnh sau: 

composer create-project --prefer-dist laravel/laravel laravel_socialite

Tiếp theo, chúng ta sẽ kết nối với cơ sở dữ liệu như sau:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_socialite
DB_USERNAME=root
DB_PASSWORD=

Cài đặt Jetstream trong Laravel

Đầu tiên, chúng ta sẽ cài đặt thư viện Jetstream bằng lệnh sau:

composer require laravel/jetstream

Tiếp theo, chúng ta sẽ sử dụng lệnh sau để tạo các template xác thực:

php artisan jetstream:install livewire

Sau đó, chúng ta sẽ build assets bằng lệnh sau:

npm install && npm run dev

 Cuối cùng, hãy chạy lệnh sau để tạo cấu trúc bảng cơ sở dữ liệu:

php artisan migrate

Cài đặt Socialite trong Laravel

Đầu tiên, chúng ta sẽ cài đặt thư viện Socialite bằng lệnh sau:

composer require laravel/socialite

Tiếp theo, mở tệp config/app.php và thêm service socialite như sau:

....
'providers' => [
    ....
    ....
    Laravel\Socialite\SocialiteServiceProvider::class,
],

'aliases' => [
    ....
    ....
    'Socialite' => Laravel\Socialite\Facades\Socialite::class,
],
....

Trong dự án, chúng ta có thể sử dụng nhiều tài khoản mạng xã hội khác nhau, vì vậy chúng ta cần một bảng để lưu thông tin tài khoản mạng xã hội, lệnh như sau:

php artisan make:migration create_social_accounts_table

Sau đó, bạn hãy chỉnh sửa nội dung migrate trên như sau:

<?php

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

class CreateSocialAccountsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('social_accounts', function (Blueprint $table) {
            $table->id();
            $table->integer('user_id');
            $table->string('provider_user_id');
            $table->string('provider');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('social_accounts');
    }
}

Sau khi chỉnh sửa, hãy chạy lệnh sau để tạo cấu trúc bảng social_accounts:

php artisan migrate

Tiếp theo, chúng ta sẽ tạo model cho bảng social_accounts bằng lệnh sau:

php artisan make:model SocialAccount

Tiếp theo, chúng ta sẽ sử dụng lệnh sau để tạo model cho bảng social_accounts:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class SocialAccount extends Model
{
    use HasFactory;
    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected $fillable = [
        'user_id',
        'provider',
        'provider_user_id',
    ];

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

Nhân tiện, hãy chỉnh sửa model bảng users như sau:

<?php

namespace App\Models;
...
class User extends Authenticatable
{   
    ...
    public function socialAccounts()
    {
        return $this->hasMany(SocialAccount::class);
    }
}

Tiếp theo, chúng ta sẽ tạo một controller xử lý thông tin đăng nhập bằng lệnh sau:

php artisan make:controller SocialAuthController

 Sau khi tạo xong, hãy chỉnh sửa nội dung controller như sau:

<?php

namespace App\Http\Controllers;

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

class SocialAuthController extends Controller
{
    public function redirectToProvider($provider)
    {
        try {
            return Socialite::driver($provider)->redirect();
        } catch (Throwable $e) {
            return redirect()->route('login');
        }
    }

    public function handleProviderCallback($provider)
    {
        $user = self::createOrGetUser(Socialite::driver($provider));
        if ($user) {
            Auth::login($user);
            return redirect()->route('dashboard');
        }
        return redirect()->route('login');
    }

    public function createOrGetUser(Provider $provider)
    {
        try {
            $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'         => $providerName,
                    'provider_user_id' => $providerUser->getId(),
                ]);
                $user = User::whereEmail($providerUser->getEmail())->first();
                if (!$user) {
                    $user = User::create([
                        'email'    => $providerUser->getEmail(),
                        'name'     => $providerUser->getName(),
                        'password' => encrypt('ManhDanBlogs')
                    ]);
                }
                $account->user()->associate($user);
                $account->save();
                return $user;
            }
        } catch (Throwable $e) {
            return false;
        }
    }
}

Cuối cùng, mở tệp web.php và thêm hai route xử lý đăng nhập như sau:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\SocialAuthController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
...
Route::get('auth/{social}', [SocialAuthController::class, 'redirectToProvider']);
Route::get('auth/{social}/callback', [SocialAuthController::class, 'handleProviderCallback']);

Đăng kí Facebook Client ID and Secret

Trước hết, bạn phải có tài khoản Facebook, nếu chưa có, bạn có thể đăng ký Facebook tại đây.

Sau khi bạn có tài khoản Facebook và truy cập trang Facebook Developers Console để tạo Client ID và Client Secret cho ứng dụng Facebook.

Bước 1: Đầu tiên, chúng ta sẽ nhấn nút "Tạo ứng dụng" để tạo ra một ứng dụng facebook mới như hình bên dưới.

Bước 2: Bạn hãy chọn loại ứng dụng phù hợp với website của mình, ở đây mình sẽ chọn "Người tiêu dùng" và nhấn nút "Tiếp".

Bước 3: Điền các thông tin về ứng dụng của bạn và nhấn nút "Tạo ứng dụng" như hình bên dưới.

Bước 4: Nhấn nút "Thiết lập" ở mục Đăng nhập bằng Facebook như hình bên dưới.

Bước 5: Nhấn nút "Cài đặt" ở mục Đăng nhập bằng Facebook như hinh bên dưới.

Bước 6: Điền URL vào mục "URL chuyển hứng OAuth hợp lệ" như hình bên dưới.

Bước 7: Chọn Thông tin cơ bản ở mục Cài đặt như hình bên dưới.

Bước 8: Bạn sẽ thông tin client id và secret của ứng dụng Facebook như hình bên dưới.

Sau khi đã có thông tin Client ID và Client Secret, chúng ta sẽ đăng kí thông tin Facebook vào tệp config/services.php như sau:

<?php

return [
    ...
    'facebook' => [
        'client_id' => env('FACEBOOK_CLIENT_ID'),
        'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
        'redirect' => env('FACEBOOK_CLIENT_REDIRECT'),
    ],

];

Cuối cùng, mở tệp .env và thêm cấu hình sau:

FACEBOOK_CLIENT_ID=client_id
FACEBOOK_CLIENT_SECRET=client_secret
FACEBOOK_CLIENT_REDIRECT=https://laravel-socialite.com/auth/facebook/callback

Trải nghiệm đăng nhập Facebook Socialite

Đầu tiên, hãy chỉnh sửa nội dung của tệp views/auth/login.blade.php như sau:

<x-guest-layout>
    <x-jet-authentication-card>
        <x-slot name="logo">
            <x-jet-authentication-card-logo />
        </x-slot>

        <x-jet-validation-errors class="mb-4" />

        @if (session('status'))
            <div class="mb-4 font-medium text-sm text-green-600">
                {{ session('status') }}
            </div>
        @endif

        <form method="POST" action="{{ route('login') }}">
            @csrf

            <div>
                <x-jet-label for="email" value="{{ __('Email') }}" />
                <x-jet-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus />
            </div>

            <div class="mt-4">
                <x-jet-label for="password" value="{{ __('Password') }}" />
                <x-jet-input id="password" class="block mt-1 w-full" type="password" name="password" required autocomplete="current-password" />
            </div>

            <div class="block mt-4">
                <label for="remember_me" class="flex items-center">
                    <x-jet-checkbox id="remember_me" name="remember" />
                    <span class="ml-2 text-sm text-gray-600">{{ __('Remember me') }}</span>
                </label>
            </div>

            <div class="flex items-center justify-end mt-4">
                @if (Route::has('password.request'))
                    <a class="underline text-sm text-gray-600 hover:text-gray-900" href="{{ route('password.request') }}">
                        {{ __('Forgot your password?') }}
                    </a>
                @endif

                <x-jet-button class="ml-4">
                    {{ __('Log in') }}
                </x-jet-button>
            </div>

            <div class="flex items-center justify-end mt-4">
                <a class="btn" href="{{ url('auth/facebook') }}"
                    style="background: #0073fa; color: #ffffff; padding: 10px; width: 100%; text-align: center; display: block; border-radius:3px;">
                    Login with Facebook
                </a>
            </div>
        </form>
    </x-jet-authentication-card>
</x-guest-layout>

Bạn có thể đăng nhập vào Facebook bằng URL sau:

https://laravel-socialite.com/login


CÓ THỂ BẠN QUAN TÂM

Method WhereAny / WhereAll  in Laravel Eloquent

Method WhereAny / WhereAll in Laravel Eloquent

New Laravel 10: Eloquent WhereAny() và WhereAll() Laravel cung cấp cho chúng ta khả năng xây dựng các truy vấn dữ liệu mạnh mẽ với Eloquent ORM, giúp chúng ta có thể xử lý các truy vấn cơ sở dữ li...

Laravel User Authentication

Laravel User Authentication

Trong hướng dẫn này, tôi sẽ hướng dẫn bạn xây dựng chức năng đăng nhập trong Laravel. Công bằng mà nói thì bạn có thể sử dụng Laravel UI hoặc JetStream để tự động tạo ra chức năng đăng nhập trong Lara...

Integrating CKFinder into CKEditor 5 in Laravel 11

Integrating CKFinder into CKEditor 5 in Laravel 11

CKEditor 5 CKEditor 5 là một trình soạn thảo văn bản phong phú JavaScript với nhiều tính năng và khả năng tùy chỉnh. CKEditor 5 có kiến trúc MVC hiện đại, mô hình dữ liệu tùy chỉnh và DOM ảo, mang...

How to Install Laravel on CentOS 6/7

How to Install Laravel on CentOS 6/7

Laravel là một PHP Framework mã nguồn mở miễn phí, được phát triển bởi Taylor Otwell với phiên bản đầu tiên được ra mắt vào 6/2011. Laravel ra đời nhằm mục đích phát triển ứng dụng web dựa trên mô hìn...

Laravel Custom Eloquent Casts

Laravel Custom Eloquent Casts

Trước đây, chúng ta bị giới hạn cast mặc định do Laravel cung cấp. Mặc dù, có một số gói thư viện có thể  giúp chúng ta custom được nhưng chúng có một nhược điểm lớn. Bởi vì, chúng ghi đề phương thức...

Integrating Google Gemini AI in Laravel

Integrating Google Gemini AI in Laravel

Google Gemini Gemini là một mô hình trí tuệ nhân tạo mới mạnh mẽ từ Google không chỉ có khả năng hiểu văn bản mà còn có thể hiểu cả hình ảnh, video và âm thanh. Gemini là một mô hình đa phương ti...

Simplify Your Laravel Workflow with Laravel Pint

Simplify Your Laravel Workflow with Laravel Pint

Laravel Pint là gì? Laravel Pint là một công cụ sửa đổi mã nguồn của bạn để mã nguồn của bạn tuân thủ theo các tiêu chuẩn. Nói một cách khác, Laravel Pint sẽ quét toàn bộ mã nguồn của bạn, phát...

Laravel Migration

Laravel Migration

Migration cho phép các nhà phát triển (Developer) nhanh chóng tạo ra cở sở dữ liệu của ứng dụng mà không cần vào màn hình quản lý cơ sở dữ liệu hay chạy bất kì một câu lệnh SQL nào. Trước hết, nếu...

Laravel One to Many Eloquent Relationship

Laravel One to Many Eloquent Relationship

One to Many Relationship được sử dụng trong trường hợp một dữ liệu của một bảng được liên kết với một hoặc nhiều dữ liệu ở bảng khác. Ví dụ, một bài post có thể có nhiều comment. Vì vậy, trong hướn...

ManhDanBlogs