+8

Multiple Authenticate trong Laravel 8

Như các bạn biết mỗi một hệ thống website thông thường sẽ có một hệ thống cho Admin quản trị và một hệ thống dành cho User thông thường sử dụng, chính vì thế các website rất cần sử dụng Multiple Authenticate. Hãy cùng mình tìm hiểu cách xây dựng chúng trong Laravel nhé!

I. Chuẩn bị Project

1. Tạo project

Tạo một project laravel bằng composer với câu lệnh

composer create-project --prefer-dist laravel/laravel multiple-auth

2. Cơ sở dữ liệu

a. File .env

Mở project lên và thực hiện chỉnh sửa file .env để kết nối cơ sở dữ liệu. Ở đây mình dùng mysql

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=<database_name>
DB_USERNAME=<username>
DB_PASSWORD=<password>

Trong đó,

  • <database_name> là tên cơ sở dữ liệu của bạn tạo ra ở mysql,
  • <username> là tên đăng nhập để truy cập vào database, thông thường <username>root.
  • <password> là mật khẩu để truy cập vào database, thông thường <password> trống, nếu bạn có đặt mật khẩu thì thay thế bằng mật khẩu bạn đã cấu hình.

b. Cấu trúc các bảng

Để sử dụng được multiple authenticate chúng ta cần hai bảng admins và users để lưu thông tin đăng nhập cho hai loại đối tượng này.

Admins

Tạo bảng admins bằng cách dùng migration

php artisan make:migration create_admins_table --create=admins

Chạy câu lệnh trên để tạo một migration mới cho bảng admins và thêm các cột gồm: id, email, password, timestamps

    public function up()
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

Users

Bảng users cũng có cấu trúc tương tự với bảng admin nên chúng ta có thể dùng mặc định của laravel đã tạo ra.

Chạy câu lệnh migrate để tạo các bảng

php artisan migrate

c. Seed dữ liệu

Mở file database\seeders\DatabaseSeeder.php và sửa

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        DB::table('admins')->insert([
            [
                'name' => 'Admin',
                'email' => 'admin@gmail.com',
                'password' => bcrypt('admin123'),
            ]
        ]);

        DB::table('users')->insert([
            [
                'name' => 'User',
                'email' => 'user@gmail.com',
                'password' => bcrypt('admin123'),
            ]
        ]);
    }
}

Chạy lệnh sau để seed dữ liệu

php artisan db:seed

3. Tạo và cấu hình Models

Trong thư mục app\Models có sẵn file User.php và tạo thêm file Admin.php tương ứng với hai bảng trên.

app/Models/Admin.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class Admin extends Authenticatable
{
    use HasFactory, Notifiable;

    protected $table = 'admins';

    protected $guarded = 'admin';

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];
}

app/Models/User.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    protected $table = 'users';

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];
}

II. Multiple Authenticate

Vậy là đã xong phần chuẩn bị cơ bản. Bây giờ chúng ta sẽ thực hiện làm nhiều luồng xác thực cho trang web.

1. Guard

Trong Laravel, Authentication có thể định nghĩa được nhiều guard, mỗi guard tương ứng với một thành phần xác thực khác nhau. Với demo này mình cần hai cái đối tượng là user và admin.

Mở file config\auth.php ra và chúng có thể thấy guard được config ở trong đây. Laravel đã làm sẵn cho chúng ta 2 guard user và api, bây giờ chúng ta làm thêm một cái cho admin nữa là được.

Tìm đến phần guards và sửa thành như sau:

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],

        'admin' => [
            'driver' => 'session',
            'provider' => 'admins',
        ],
    ],

Đoạn code trên thì guard cho user được config mặc định là web.

Tiếp theo, kéo xuống phần providers và sửa:

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Models\Admin::class, 
        ],
    ],

2. Routes

Thông thường các route của hai trang này có thể viết chung một file route là web.php cũng được nhưng theo mình nghĩ thì chúng ta nên tách thêm một cái file route dành riêng cho admin thì sẽ dễ dàng sử dụng hơn.

Trong folder route tạo một file admin.php và config để các route được khai báo trong file này có thể chạy được đúng cách.

Mở file app/Providers/RouteServiceProvider.php và sửa như sau:

    public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));

            Route::middleware('web')
                ->prefix('admin')
                ->namespace($this->namespace)
                ->group(base_path('routes/admin.php'));
        });
    }

Trên đây mình đã định nghĩa một nhóm route có prefix là admin nằm trong file routes/admin.php rồi, như vậy trong file route/admin.php thay vì địng nghĩa đường link admin/login thì mình chỉ cần định nghĩa chúng với đường link /login tương tự như bên web.

Định nghĩa các route cho admin trong file routes/admin.php

<?php

use App\Http\Controllers\Admin\Auth\LoginController;
use App\Http\Controllers\Admin\HomeController;
use Illuminate\Support\Facades\Route;

Route::match(['get', 'post'], '/login', [LoginController::class, 'login'])->name('admin.login');
Route::middleware('auth:admin')->group(function (){
    Route::get('/', [HomeController::class, 'index'])->name('dashboard');
});

Với route này khi bạn truy cập đường dẫn /admin nó sẽ tìm tới controller app/Controller/Admin/HomeController và thực hiện các hành động trong hàm index. Middleware phải là auth:admin (middleware này thực hiện với guard là admin).

Định nghĩa các route cho admin trong file routes/web.php

<?php

use App\Http\Controllers\User\Auth\LoginController;
use App\Http\Controllers\User\HomeController;
use Illuminate\Support\Facades\Route;

Route::match(['get', 'post'], '/login', [LoginController::class, 'login'])->name('login');
Route::middleware('auth')->group(function (){
    Route::get('/', [HomeController::class, 'index'])->name('home');
});

Phần route user cũng như vậy nhưng chỉ cần dùng middleware auth là được rồi, mặc định của laravel sẽ thực hiện với guard web (trỏ vào user).

3. Controllers

a. Admin

Tạo LoginController cho guard admin bằng lệnh

php artisan make:controller Admin/Auth/LoginController

Sửa file app\Http\Controllers\Admin\Auth\LoginController.php như dưới đây

<?php

namespace App\Http\Controllers\Admin\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    public function login(Request $request)
    {
        if ($request->getMethod() == 'GET') {
            return view('admin.auth.login');
        }

        $credentials = $request->only(['email', 'password']);
        if (Auth::guard('admin')->attempt($credentials)) {
            return redirect()->route('dashboard');
        } else {
            return redirect()->back()->withInput();
        }
    }
}

Tạo HomeController cho guard admin bằng lệnh

php artisan make:controller Admin/HomeController

Sửa file app\Http\Controllers\Admin\HomeController.php như dưới đây

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class HomeController extends Controller
{
    public function index()
    {
        $user = Auth::guard('admin')->user();
        echo 'Xin chào Admin, '. $user->name;
    }
}

b. User

Tạo LoginController cho guard user bằng lệnh

php artisan make:controller User/Auth/LoginController

Sửa file app\Http\Controllers\User\Auth\LoginController.php như dưới đây

<?php

namespace App\Http\Controllers\User\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    public function login(Request $request)
    {
        if ($request->getMethod() == 'GET') {
            return view('user.auth.login');
        }

        $credentials = $request->only(['email', 'password']);
        if (Auth::attempt($credentials)) {
            return redirect()->route('home');
        } else {
            return redirect()->back()->withInput();
        }
    }
}

Tạo HomeController cho guard user bằng lệnh

php artisan make:controller User/HomeController

Sửa file App\Http\Controllers\User\HomeController.php như dưới đây

<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class HomeController extends Controller
{
    public function index()
    {
        $user = Auth::user();
        echo 'Xin chào User, '. $user->name;
    }
}

4. Giao diện Login

Dựng giao diện cho các trang mà nãy giờ chúng ta gọi đến trong controller. Trong bài viết này mình chỉ dựng giao diện đơn giản. Mỗi bạn có một cách riêng có thể tự dựng hoặc dùng themes tùy mọi người.

Tạo file giao diện login cho guard admin trong resoures/view/admin/auth/login.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>Admin Login</title>
</head>
<body>
<form method="POST" action="{{ route('admin.login') }}">
    @csrf
    <h1>Admin</h1>
    <input type="text" name="email" placeholder="Nhập địa chỉ email">
    <input type="password" name="password" placeholder="Nhập mật khẩu">
    <button type="submit">Đăng nhập</button>
</form>
</body>
</html>

Tương tự tạo file giao diện login cho guard user trong resoures/view/user/auth/login.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>User Login</title>
</head>
<body>
<form method="POST" action="{{ route('login') }}">
    @csrf
    <h1>User</h1>
    <input type="text" name="email" placeholder="Nhập địa chỉ email">
    <input type="password" name="password" placeholder="Nhập mật khẩu">
    <button type="submit">Đăng nhập</button>
</form>
</body>
</html>

III. Tổng kết

Chạy lệnh sau và mở trình duyệt để test thành quả nào

php artisan serve

Như vậy là mình vừa hướng dẫn xong các bạn cách xây dựng Multiple Authenticate trong Laravel. Hy vọng bài viết này có thể giúp ích cho mọi người ♥️♥️♥️

IV. Tài liệu tham khảo

https://pusher.com/tutorials/multiple-authentication-guards-laravel

https://viblo.asia/p/multiple-authenticate-trong-laravel-XL6lANJm5ek


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí