Integrasi Admin LTE dengan Laravel Custom Auth #Part 1
Pada tutorial kali ini saya akan memberikan guideline untuk membuat custom authentication yang terintegrasi dengan Admin LTE menggunakan framework Laravel 10.
Selamat mencoba ….. 👌
Kebutuhan yang perlu kalian install:
- Installasi Composer : https://getcomposer.org/download/
- Installasi Node Js : https://getcomposer.org/download/
Baik jika sudah install kebutuhan diatas , kalian bisa lanjutkan tutorial berikutnya.
1. Installasi Project
Jalankan Visual Studio Code , buka folder htdocs dan buatlah terminal baru.
Lakukan perintah dibawah untuk melakukan installasi project laravel
composer create-project --prefer-dist laravel/laravel BookStore
Jika download projectnya berhasil maka kalian bisa membuka folder BookStore pada Visual Studio Code seperti gambar dibawah:
2. Konfigurasi Database
Buka localhost/phpmyadmin pada browser atau klik admin pada module mysql di xampp
Buatlah database baru dengan nama : db_bookstore
Buka file .env , isi konfigurasi pada database seperti contoh dibawah:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db_bookstore
DB_USERNAME=root
DB_PASSWORD=
3. Migrations User
Buka file database/migrations/2014_10_12_000000_create_users_table.php , kita akan menambahkan kolom fullname dan level. Sehingga table user dapat kita lihat seperti contoh dibawah:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('fullname');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('level');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('users');
}
};
Lakukan perintah migrate untuk generate tabel seperti dibawah:
php artisan migrate
Jika berhasil maka akan muncul pesan Done seperti dibawah:
4. Membuat Auth
Lakukan perintah composer untuk mendownload library laravel/ui seperti dibawah:
composer require laravel/ui
Jika sudah berhasil , maka kita lakukan install modul auth dengan perintah dibawah:
php artisan ui bootstrap --auth
Selanjutnya , kita jalankan npm install && npm run dev agar modul auth dapat digunakan seperti perintah dibawah:
npm install && npm run dev
Jika berhasil, maka akan menampilkan vite seperti dibawah:
5. Membuat Custom Auth
- Buatlah controller AuthController dengan lakukan perintah dibawah:
php artisan make:controller AuthController
- Konfigurasi Routes pada pada file web.php
// comment auth default dibawah
// Auth::routes();
Route::get('login',[AuthController::class,'index'])->name('login');
Route::get('register',[AuthController::class,'register'])->name('register');
Route::get('dashboard',[AuthController::class,'dashboard'])->name('dashboard');
Route::post('proses_login',[AuthController::class,'proses_login'])->name('proses.login');
Route::post('proses_register',[AuthController::class,'proses_register'])->name('proses.register');
Route::post('logout',[AuthController::class,'logout'])->name('logout');
// ini di komen juga
// Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Notes:
- AuthController harus di ketik manual karna tidak akan muncul namespace nya jika hanya di copy
Buka Auth Model
Buka file app/Models/User.php dan kita ubah variabel fillable seperti dibawah:
protected $fillable = [
'fullname',
'email',
'password',
'level'
];
Buka Auth Controller
Buka file app/Http/Controllers/AuthController.php, lalu kita buat fungsi login,register,proses_register,dashboard, dan logout seperti kode program dibawah:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class AuthController extends Controller
{
//
public function index(){
return view('auth.login');
}
public function register(){
return view('auth.register');
}
public function proses_login(Request $request){
// isi credential hanya berupa username dan password
$credentials = $request->only('email','password');
//validasi menggunakan Illuminate\Support\Facades\Validator
//isi field validasi dan rules nya yaitu wajib di isi
$validate = Validator::make($credentials,[
'email'=>'required|email',
'password'=>'required'
]);
// jika terdapat field yang kosong
if($validate->fails()){
//kembali ke halaman login & tampilkan error pada setiap inputnya
return back()->withErrors($validate)->withInput();
}
// verifikasi data user pada kolom email dan password sesuai atau belum
if(Auth::attempt($credentials)){
//jika sesuai maka jalankan fungsi dashboard
return redirect()->intended('dashboard')->with('success','Successfully Login');
}
// kembali ke halaman login dan tampilkan pesan error pada login_error
return redirect('login')->withInput()->withErrors(['login_error'=>'Username or password are wrong!']);
}
public function dashboard(){
// cek berhasil login
if(Auth::check()){
return view('home');
}
return redirect('login')->with('You dont have access');
}
public function proses_register(Request $request){
//validasi menggunakan Illuminate\Support\Facades\Validator
//isi field validasi dan rules nya yaitu wajib di isi
$validate = Validator::make($request->all(),[
'fullname'=>'required',
'email'=>'required|email',
'password'=>'required',
'password_confirm' => 'required|confirmed',
]);
// jika terdapat field yang kosong
if($validate->fails()){
//kembali ke halaman login & tampilkan error pada setiap inputnya
return back()->withErrors($validate)->withInput();
}
// tambahkan field level dan kita isi dengan admin
$request['level'] = 'admin';
// panggil model User dan jalankan fungsi ORM create untuk melakukan insert semua data
User::create($request->all());
return redirect('dashboard')->with('success','You have successfully register');
}
public function logout(){
// clear session dan memberitahu auth dengan status logout
Session::flush();
Auth::logout();
return Redirect('login');
}
}
Buka UI layout
selanjutnya buka file resources/views/layouts/app.blade.php , lalu ubah tampilan pada app seperti dibawah:
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>
<!-- Scripts -->
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
</head>
<body>
<div id="app">
{{-- komen atau hapus bagian navigasi --}}
{{-- <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
<div class="container">
<a class="navbar-brand" href="{{ url('/') }}">
{{ config('app.name', 'Laravel') }}
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- Left Side Of Navbar -->
<ul class="navbar-nav me-auto">
</ul>
<!-- Right Side Of Navbar -->
<ul class="navbar-nav ms-auto">
<!-- Authentication Links -->
@guest
@if (Route::has('login'))
<li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
</li>
@endif
@if (Route::has('register'))
<li class="nav-item">
<a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
</li>
@endif
@else
<li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
{{ Auth::user()->name }}
</a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
@csrf
</form>
</div>
</li>
@endguest
</ul>
</div>
</div>
</nav> --}}
<main class="py-4">
@yield('content')
</main>
</div>
<script type="text/javascript">
// gunakan jQuery dan panggil class close ketika di klik maka alert-warning menghilang dengan efek fadeout
$('.close').click(function (e) {
$('.alert-warning').fadeOut();
});
</script>
</body>
</html>
Buka UI login
Selanjutnya buka file resources/views/auth/login.blade.php, buat tampilan login sesuai kreasimu dengan contoh kode program dibawah:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Login') }}</div>
<div class="card-body">
{{-- jika ada error maka tampilkan pesan login_error --}}
@error('login_error')
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>{{ $message }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@enderror
{{-- ganti action ke route name yaitu proses.login --}}
<form method="POST" action="{{ route('proses.login') }}">
@csrf
<div class="row mb-3">
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password Confirm') }}</label>
<div class="col-md-6">
<input id="password_confirm" type="password" class="form-control @error('password_confirm') is-invalid @enderror" name="password_confirm" required autocomplete="current-password">
@error('password_confirm')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label" for="remember">
{{ __('Remember Me') }}
</label>
</div>
</div>
</div>
<div class="row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-success">
{{ __('Login') }}
</button>
<a class="btn btn-link" href="{{ route('register') }}">
{{ __('Register') }}
</a>
@if (Route::has('password.request'))
<a class="btn btn-link" href="{{ route('password.request') }}">
{{ __('Forgot Your Password?') }}
</a>
@endif
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Buka UI register
Selanjutnya buka file resources/views/auth/register.blade.php, buatlah tampilan register sesuai kreasimu dengan contoh kode program dibawah:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Register') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('proses.register') }}">
@csrf
<div class="row mb-3">
<label for="name" class="col-md-4 col-form-label text-md-end">{{ __('Full Name') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('fullname') is-invalid @enderror" name="fullname" value="{{ old('fullname') }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Confirm Password') }}</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<div class="row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Notes:
- Berikan attribute name seuai dengan model user pada setiap tag input
- Ubah attribute action pada form ke route(‘proses.register’)
Integrasi Dengan Admin LTE
Setelah berhasil login maka kita bisa integrasikan dengan template adminlte agar tampilan dashboard terlihat lebih elegan dan sesuai dengan fungsi admin.
Installasi Admin LTE
Lakukan perintah dibawah untuk menginstall library laravel-adminlte
composer require jeroennoten/laravel-adminlte
Jika berhasil maka akan muncul tampilan seperti dibawah:
Selanjutnya kita akan install admin lte seperti dibawah:
php artisan adminlte:install
Konfigurasi Layout Home
Selanjutnya kita akan panggil layout yang sudah di provide oleh adminlte sehingga sekarang tampilannya menjadi seperti dibawah:
@extends('adminlte::page')
@section('title','Dashboard')
@section('content')
<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-header">{{ __('Dashboard') }}</div>
<div class="card-body">
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif
{{ __('You are logged in!') }}
</div>
</div>
</div>
</div>
</div>
@stop
Notes:
- Fungsi @extends(‘adminlte::page’) untuk memanggil layout pada page adminlte
- Gunakan stop pada akhir section jika menggunakan adminlte
Tampilan Akhir
Selamat anda sudah berhasil membuat custom auth yang berintegrasi dengan admin lte. Hasil yang ditampilkan seperti dibawah: