🥳BelongsToMany full, có chức năng phần quyền auth, validateCredentials, use ✔️ with (ok)

Chú ý: Nếu không chỉnh sửa file C:\xampp\htdocs\belongstomany\config\auth.php nó sẽ sử dụng mặc định là bảng user để xác thực 😒

<?php
return [
    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */
    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],
    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session"
    |
    */
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
    ],
    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],
    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that each reset token will be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */
    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],
    ],
    /*
    |--------------------------------------------------------------------------
    | Password Confirmation Timeout
    |--------------------------------------------------------------------------
    |
    | Here you may define the amount of seconds before a password confirmation
    | times out and the user is prompted to re-enter their password via the
    | confirmation screen. By default, the timeout lasts for three hours.
    |
    */
    'password_timeout' => 10800,
];

Ta sẽ tùy chỉnh chúng thành bảnh tb_admin như sau

<?php
return [
  /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */
  'defaults' => [
    'guard' => 'web',
    'passwords' => 'customusers',
  ],
  /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session"
    |
    */
  'guards' => [
    'web' => [
      'driver' => 'session',
      'provider' => 'customusers',
    ],
  ],
  /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */
  'providers' => [
    'users' => [
      'driver' => 'eloquent',
      'model' => App\Models\User::class,
    ],
    'customusers' => [
      'driver' => 'eloquent',
      'model' => App\Models\Admin::class,
    ],
  ],
  /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that each reset token will be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */
  'passwords' => [
    'users' => [
      'provider' => 'users',
      'table' => 'password_resets',
      'expire' => 60,
      'throttle' => 60,
    ],
    'customusers' => [
      'provider' => 'customusers',
      'table' => 'password_resets',
      'expire' => 60,
    ],
  ],
  /*
    |--------------------------------------------------------------------------
    | Password Confirmation Timeout
    |--------------------------------------------------------------------------
    |
    | Here you may define the amount of seconds before a password confirmation
    | times out and the user is prompted to re-enter their password via the
    | confirmation screen. By default, the timeout lasts for three hours.
    |
    */
  'password_timeout' => 10800,
];

Ví dụ 1.1 (chỉ làm đến chức năng show quyền)

C:\xampp\htdocs\belongstomany\app\Models\Admin.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Admin extends Model {
  use HasFactory;
  public $timestamps    = true;
  protected $primaryKey = 'admin_id';
  protected $table      = 'tbl_admin';
  protected $fillable   = [
    'admin_email',
    'admin_password',
    'admin_name',
    'admin_phone',
  ];
  public function roles() {
    return $this->belongsToMany(Roles::class, 'admin_roles');
  }
  public function hasRole($role) {
    return null !== $this->roles()->where('name', $role)->first();
  }
}

C:\xampp\htdocs\belongstomany\app\Models\Roles.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Roles extends Model {
  use HasFactory;
  public $timestamps  = false; //set time to false
  protected $fillable = [
    'name',
  ];
  protected $primaryKey = 'id_roles';
  protected $table      = 'tbl_roles';
  public function admin() {
    return $this->belongsToMany(Admin::class, 'admin_roles');
  }
}

C:\xampp\htdocs\belongstomany\app\Http\Controllers\UserController.php

<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use App\Models\Admin;
class UserController extends Controller {
  public function index() {
    $admin = Admin::with('roles')->orderBy('admin_id', 'DESC')->paginate(5);
    return view('all-users')->with(compact('admin'));
  }
  public function assign_roles(Request $request) {

  }
}

C:\xampp\htdocs\belongstomany\app\Providers\AppServiceProvider.php

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Pagination\Paginator;
class AppServiceProvider extends ServiceProvider
{
  /**
   * Register any application services.
   *
   * @return void
   */
  public function register()
  {
    //
  }
  /**
   * Bootstrap any application services.
   *
   * @return void
   */
  public function boot()
  {
    Paginator::useBootstrap();
  }
}

C:\xampp\htdocs\belongstomany\resources\views\all-users.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="{{ asset('css/app.css') }}">
  <title>Document</title>
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <div class="table-responsive">
          <section class="wrapper mt-5">
            <div class="panel panel-default">
              <div class="panel-heading py-5 h3">
                Liệt kê users
              </div>
              <div class="table-responsive">
                <table class="table table-border border">
                  <thead>
                    <tr>
                      <th>Tên user</th>
                      <th>Email</th>
                      <th>Phone</th>
                      <th>Password</th>
                      <th>Author</th>
                      <th>Admin</th>
                      <th>User</th>
                      <th style="width:30px;"></th>
                    </tr>
                  </thead>
                  <tbody>
                    @foreach($admin as $key => $user)
                    <form action="{{ route('assign-roles') }}" method="POST">
                      @csrf
                      <tr>
                        <td>{{ $user->admin_name }}</td>
                        <td>
                          {{ $user->admin_email }}
                          <input type="hidden" name="admin_email" value="{{ $user->admin_email }}">
                          <input type="hidden" name="admin_id" value="{{ $user->admin_id }}">
                        </td>
                        <td>{{ $user->admin_phone }}</td>
                        <td>{{ $user->admin_password }}</td>
                        <td><input type="checkbox" name="author_role" {{$user->hasRole('author') ? 'checked' : ''}}>
                        </td>
                        <td><input type="checkbox" name="admin_role" {{$user->hasRole('admin') ? 'checked' : ''}}></td>
                        <td><input type="checkbox" name="user_role" {{$user->hasRole('user') ? 'checked' : ''}}></td>
                        <td>
                          <p><input type="submit" value="Phân quyền" class="btn btn-sm btn-outline-primary"></p>
                        </td>
                      </tr>
                    </form>
                    @endforeach
                    <tr>
                      <td colspan="8" class="text-center">
                        {{ $admin->links() }}
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </section>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

C:\Users\Administrator\Downloads\tbl_roles.sql

-- phpMyAdmin SQL Dump
-- version 5.1.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Dec 11, 2022 at 06:08 AM
-- Server version: 10.4.24-MariaDB
-- PHP Version: 7.4.28
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `elaravel`
--
-- --------------------------------------------------------
--
-- Table structure for table `tbl_roles`
--
CREATE TABLE `tbl_roles` (
  `id_roles` int(11) NOT NULL,
  `name` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `tbl_roles`
--
INSERT INTO `tbl_roles` (`id_roles`, `name`) VALUES
(1, 'admin'),
(2, 'author'),
(3, 'user');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `tbl_roles`
--
ALTER TABLE `tbl_roles`
  ADD PRIMARY KEY (`id_roles`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `tbl_roles`
--
ALTER TABLE `tbl_roles`
  MODIFY `id_roles` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

C:\Users\Administrator\Downloads\tbl_admin.sql

-- phpMyAdmin SQL Dump
-- version 5.1.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Dec 11, 2022 at 06:08 AM
-- Server version: 10.4.24-MariaDB
-- PHP Version: 7.4.28
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `elaravel`
--
-- --------------------------------------------------------
--
-- Table structure for table `tbl_admin`
--
CREATE TABLE `tbl_admin` (
  `admin_id` int(10) UNSIGNED NOT NULL,
  `admin_email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `admin_password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `admin_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `admin_phone` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `tbl_admin`
--
INSERT INTO `tbl_admin` (`admin_id`, `admin_email`, `admin_password`, `admin_name`, `admin_phone`, `created_at`, `updated_at`) VALUES
(1, 'hieuadmin@yahoo.com', '25d55ad283aa400af464c76d713c07ad', 'hieuadmin', '123456789', NULL, NULL),
(2, 'hieuauthor@yahoo.com', 'e10adc3949ba59abbe56e057f20f883e', 'hieuauthor', '123456789', NULL, NULL),
(5, 'ima06@example.net', 'e10adc3949ba59abbe56e057f20f883e', 'Allene Veum MD', '0932023992', NULL, NULL),
(6, 'janice86@example.net', 'e10adc3949ba59abbe56e057f20f883e', 'Dr. Ernie Kshlerin IV', '0932023992', NULL, NULL),
(7, 'runolfsdottir.ryleigh@example.net', 'e10adc3949ba59abbe56e057f20f883e', 'Lelah Altenwerth', '0932023992', NULL, NULL),
(8, 'tara00@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Alan Howell', '0932023992', NULL, NULL),
(9, 'jreilly@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Jacey Mueller', '0932023992', NULL, NULL),
(10, 'nicolas.sean@example.com', 'e10adc3949ba59abbe56e057f20f883e', 'Armani Quitzon', '0932023992', NULL, NULL),
(11, 'sabina20@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Dr. Eliseo Padberg DDS', '0932023992', NULL, NULL),
(12, 'doris.harber@example.com', 'e10adc3949ba59abbe56e057f20f883e', 'Hildegard Crooks', '0932023992', NULL, NULL),
(13, 'albin.kemmer@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Kailee Orn', '0932023992', NULL, NULL),
(14, 'john.schiller@example.net', 'e10adc3949ba59abbe56e057f20f883e', 'Concepcion Kshlerin', '0932023992', NULL, NULL),
(15, 'emanuel84@example.com', 'e10adc3949ba59abbe56e057f20f883e', 'Tyra Kertzmann MD', '0932023992', NULL, NULL),
(16, 'eulalia73@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Dr. Opal Daniel DVM', '0932023992', NULL, NULL),
(17, 'amara.lueilwitz@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Nicolette Gerlach DVM', '0932023992', NULL, NULL),
(18, 'kilback.royal@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Vicenta Braun', '0932023992', NULL, NULL),
(19, 'kennedi37@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Salvador Little MD', '0932023992', NULL, NULL),
(20, 'mylene20@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Colt Crona', '0932023992', NULL, NULL),
(21, 'lehner.darryl@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Estelle Homenick Sr.', '0932023992', NULL, NULL),
(22, 'gerald34@example.org', 'e10adc3949ba59abbe56e057f20f883e', 'Prof. Pietro Luettgen', '0932023992', NULL, NULL),
(23, 'genesis74@example.com', 'e10adc3949ba59abbe56e057f20f883e', 'Jonathon Wisozk', '0932023992', NULL, NULL),
(24, 'minnh@gmail.com', 'e10adc3949ba59abbe56e057f20f883e', 'Đức Nguyễn Minh', '0932023992', NULL, NULL),
(34, 'nguyenbinhminh2079@gmail.com', '', 'Binhminh Nguyen', '', NULL, NULL),
(35, 'tanhieu70@yahoo.com', '', 'Trương Hiếu', '', NULL, NULL),
(36, 'hoatamle485@gmail.com', '', 'letam hoang', '', NULL, NULL);
--
-- Indexes for dumped tables
--
--
-- Indexes for table `tbl_admin`
--
ALTER TABLE `tbl_admin`
  ADD PRIMARY KEY (`admin_id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `tbl_admin`
--
ALTER TABLE `tbl_admin`
  MODIFY `admin_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=37;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

C:\Users\Administrator\Downloads\admin_roles.sql

-- phpMyAdmin SQL Dump
-- version 5.2.0
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Dec 12, 2022 at 05:28 AM
-- Server version: 10.4.27-MariaDB
-- PHP Version: 7.4.33
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `datvietcoconut`
--
-- --------------------------------------------------------
--
-- Table structure for table `admin_roles`
--
CREATE TABLE `admin_roles` (
  `role_id_roles` int(11) NOT NULL,
  `admin_admin_id` int(10) UNSIGNED NOT NULL,
  `roles_id_roles` int(10) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
--
-- Dumping data for table `admin_roles`
--
INSERT INTO `admin_roles` (`role_id_roles`, `admin_admin_id`, `roles_id_roles`) VALUES
(1, 1, 1),
(5, 5, 3),
(6, 6, 3),
(8, 8, 3),
(9, 9, 3),
(10, 10, 3),
(11, 11, 3),
(12, 12, 3),
(13, 13, 3),
(14, 14, 3),
(15, 15, 3),
(16, 16, 3),
(17, 17, 3),
(18, 18, 3),
(19, 19, 3),
(20, 20, 3),
(21, 21, 3),
(22, 22, 3),
(25, 1, 1),
(26, 2, 2),
(27, 24, 3),
(28, 23, 3),
(30, 7, 3);
--
-- Indexes for dumped tables
--
--
-- Indexes for table `admin_roles`
--
ALTER TABLE `admin_roles`
  ADD PRIMARY KEY (`role_id_roles`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `admin_roles`
--
ALTER TABLE `admin_roles`
  MODIFY `role_id_roles` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=31;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

Ví dụ 1.2

Chú ý: Pass default dùng Auth::attempt kiểu hash

Khi dùng dạng hash với password dạng hash là

Kết quả

C:\xampp\htdocs\datvietcoconut\routes\web.php

<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
/*
|--------------------------------------------------------------------------
| 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('/', function () {
  return view('welcome');
});
Route::get('users', [UserController::class, 'index']);
Route::post('assign-roles', [UserController::class, 'assign_roles'])->name('assign-roles');
// == use group
Route::group(['middleware' => 'auth.roles'], function () {
  Route::get('test-auth', [UserController::class, 'test_auth']);
});
Route::get('admin', [UserController::class, 'admin']);
Route::post('loginadmin', [UserController::class, 'loginadmin']);

C:\xampp\htdocs\datvietcoconut\app\Http\Controllers\UserController.php

<?php
namespace App\Http\Controllers;
use App\Models\Admin;
use Auth;
use Illuminate\Http\Request;
class UserController extends Controller
{
  public function index()
  {
    $admin = Admin::with('roles')->orderBy('admin_id', 'DESC')->paginate(5);
    return view('all-users')->with(compact('admin'));
  }
  public function assign_roles(Request $request)
  {
  }
  public function test_auth()
  {
    return "Test - Auth only use Admin or Author 😒";
  }
  public function admin()
  {
    return view('login');
  }
  public function loginadmin(Request $request)
  {
    if (
      Auth::attempt([
        'admin_email' => $request->admin_email,
        'password' => $request->admin_password,
      ])
    ) {
      return redirect('/test-auth');
    } else {
      return redirect('admin')->with('message', 'Lỗi đăng nhập authentication');
    }
  }
}

C:\xampp\htdocs\datvietcoconut\app\Http\Middleware\AccessPermission.php


<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Auth;
use App\Models\Role;
class AccessPermission
{
  /**
   * Handle an incoming request.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
   * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
   */
  public function handle(Request $request, Closure $next)
  {
    if (Auth::user()->hasAnyRoles(['admin', 'author'])) {
      return $next($request);
    }
    return redirect('/');
  }
}

C:\xampp\htdocs\datvietcoconut\app\Models\Role.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Role extends Model {
  use HasFactory;
  public $timestamps  = false; //set time to false
  protected $fillable = [
    'name',
  ];
  protected $primaryKey = 'id_roles';
  protected $table      = 'tbl_roles';
  public function admin() {
    return $this->belongsToMany(Admin::class, 'admin_roles');
  }
}

C:\xampp\htdocs\datvietcoconut\resources\views\all-users.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="{{ asset('css/app.css') }}">
  <title>Document</title>
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <div class="table-responsive">
          <section class="wrapper mt-5">
            <div class="panel panel-default">
              <div class="panel-heading py-5 h3">
                Liệt kê users
              </div>
              <div class="table-responsive">
                <table class="table table-border border">
                  <thead>
                    <tr>
                      <th>Tên user</th>
                      <th>Email</th>
                      <th>Phone</th>
                      <th>Password</th>
                      <th>Author</th>
                      <th>Admin</th>
                      <th>User</th>
                      <th style="width:30px;"></th>
                    </tr>
                  </thead>
                  <tbody>
                    @foreach($admin as $key => $user)
                    <form action="{{ route('assign-roles') }}" method="POST">
                      @csrf
                      <tr>
                        <td>{{ $user->admin_name }}</td>
                        <td>
                          {{ $user->admin_email }}
                          <input type="hidden" name="admin_email" value="{{ $user->admin_email }}">
                          <input type="hidden" name="admin_id" value="{{ $user->admin_id }}">
                        </td>
                        <td>{{ $user->admin_phone }}</td>
                        <td>{{ $user->admin_password }}</td>
                        <td><input type="checkbox" name="author_role" {{$user->hasRole('author') ? 'checked' : ''}}>
                        </td>
                        <td><input type="checkbox" name="admin_role" {{$user->hasRole('admin') ? 'checked' : ''}}></td>
                        <td><input type="checkbox" name="user_role" {{$user->hasRole('user') ? 'checked' : ''}}></td>
                        <td>
                          <p><input type="submit" value="Phân quyền" class="btn btn-sm btn-outline-primary"></p>
                        </td>
                      </tr>
                    </form>
                    @endforeach
                    <tr>
                      <td colspan="8" class="text-center">
                        {{ $admin->links() }}
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </section>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

C:\xampp\htdocs\datvietcoconut\app\Http\Kernel.php

protected $routeMiddleware = [
// ...
    'auth.roles' => \App\Http\Middleware\AccessPermission::class,
// ...
];

C:\xampp\htdocs\datvietcoconut\config\auth.php

<?php
return [
  /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */
  'defaults' => [
    'guard' => 'web',
    'passwords' => 'customusers',
  ],
  /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session"
    |
    */
  'guards' => [
    'web' => [
      'driver' => 'session',
      'provider' => 'customusers',
    ],
  ],
  /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */
  'providers' => [
    'users' => [
      'driver' => 'eloquent',
      'model' => App\Models\User::class,
    ],
    'customusers' => [
      'driver' => 'eloquent',
      'model' => App\Models\Admin::class,
    ],
  ],
  /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that each reset token will be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */
  'passwords' => [
    'users' => [
      'provider' => 'users',
      'table' => 'password_resets',
      'expire' => 60,
      'throttle' => 60,
    ],
    'customusers' => [
      'provider' => 'customusers',
      'table' => 'password_resets',
      'expire' => 60,
    ],
  ],
  /*
    |--------------------------------------------------------------------------
    | Password Confirmation Timeout
    |--------------------------------------------------------------------------
    |
    | Here you may define the amount of seconds before a password confirmation
    | times out and the user is prompted to re-enter their password via the
    | confirmation screen. By default, the timeout lasts for three hours.
    |
    */
  'password_timeout' => 10800,
];

C:\xampp\htdocs\datvietcoconut\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;
  public $timestamp     = false;
  protected $table      = 'tbl_admin';
  protected $primaryKey = 'admin_id';
  protected $fillable   = [
    'admin_email',
    'admin_password',
    'admin_name',
    'admin_phone',
  ];
  public function getAuthPassword() {
    return $this->admin_password;
  }
  public function roles() {
    return $this->belongsToMany(Role::class, 'admin_roles');
  }
  public function hasRole($role) {
    if ($this->roles()->where('name', $role)->first()) {
      return true;
    }
    return false;
  }
  public function hasAnyRoles($roles) {
    if (is_array($roles)) {
      foreach ($roles as $role) {
        if ($this->hasRole($role)) {
          return true;
        }
      }
    } else {
      if ($this->hasRole($roles)) {
        return true;
      }
    }
    return false;
  }
}

C:\xampp\htdocs\datvietcoconut\app\Models\Role.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Role extends Model {
  use HasFactory;
  public $timestamps  = false; //set time to false
  protected $fillable = [
    'name',
  ];
  protected $primaryKey = 'id_roles';
  protected $table      = 'tbl_roles';
  public function admin() {
    return $this->belongsToMany(Admin::class, 'admin_roles');
  }
}

Bản viết gọn của C:\xampp\htdocs\datvietcoconut\app\Http\Middleware\AccessPermission.php

<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Auth;
use App\Models\Role;
use Illuminate\Support\Facades\Route;
class AccessPermission
{
  /**
   * Handle an incoming request.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
   * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
   */
  public function handle(Request $request, Closure $next)
  {
    $actions = Route::getCurrentRoute()->getAction();
    $roles = isset($actions['auth.roles']) ? $actions['auth.roles'] : null;
    if (Auth::user()->hasAnyRoles($roles) || !$roles) {
      return $next($request);
    } else {
      return redirect('admin');
    }
  }
}

C:\xampp\htdocs\datvietcoconut\routes\web.php

<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
/*
|--------------------------------------------------------------------------
| 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('/', function () {
  return view('welcome');
});
Route::get('users', [UserController::class, 'index']);
Route::post('assign-roles', [UserController::class, 'assign_roles'])->name('assign-roles');
// == use group
Route::group(['middleware' => 'auth.roles','auth.roles'=>['admin','author']], function () {
  Route::get('test-auth', [UserController::class, 'test_auth']);
});
Route::get('admin', [UserController::class, 'admin']);
Route::post('loginadmin', [UserController::class, 'loginadmin']);

Last updated