Tanggal :23 April 2024
Membuat Autentikasi Manual di Laravel

Membuat Autentikasi Manual di Laravel

Assalamualaikum Warohmatulloh Wabarokatuh, Sejatinya Laravel menyediakan starter kit untuk menangani autentikasi seperti Laravel Breeze, Laravel Jetstream. Namun ada kalanya kita ingin Membuat Autentikasi Manual di Laravel pada kondisi tertentu, bagaimana caranya? simak terus tulisan ini.

Menginstal Laravel

Langkah pertama instal terlebih dahulu Laravelnya, gunakan perintah ini.

laravel new auth-manual

Jika kalian belum menginstal Laravel Installer, bisa gunakan composer.

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

Konfigurasi Proyek Laravel

Setelah selesai menginstal Laravel, selanjutnya kita konfigurasikan proyeknya. Gak banyak kok, kali ini kita cuma butuh database aja. Buat database baru dengan nama auth_manual misalnya.

Kemudian sesuaikan pada file .env

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

Kemudian jalankan migrationnya, agar tabel tabel bawaan Laravel terbuat di dalam database.

php artisan migrate

Harusnya ada beberapa tabel baru di database kita, salah satunya tabel user .

Membuat Fungsi Register

Kita mulai dari yang paling gampang dulu ya, kita buat fungsi untuk pendaftaran (register). Pertama kita buat sebuah Controller RegisterController.php dengan perintah artisan.

php artisan make:controller RegisterController

Setelah itu, buat sebuah method misalnya create() untuk menampilkan view / halaman registernya.

use Illuminate\Http\Request;

class RegisterController extends Controller
{
    public function create()
    {
        return view('auth.register');
    }
    
    // ....
}

Kemudian kita daftarkan routenya pada routes/web.php

Route::get('/register', [\App\Http\Controllers\RegisterController::class, 'create'])->name('register');

Kemudian agar ketika nanti diakses tidak eror, kita perlu membuat file .blade.php atau view. Sesuai pada method create() tadi, maka kita akan buat viewnya di dalam resources/views kemudian buat sebuah folder baru auth dan buat file dengan nama register.blade.php.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">
    <title>Register</title>
</head>
<body>
<div class="container-sm">
    <div class="card">
        <div class="card-body">
            <form action="" method="post">
                @csrf
                <div class="mb-3">
                    <label for="name" class="form-label">Name</label>
                    <input type="text" class="form-control @error('name') is-invalid @enderror" id="name"
                           name="name" placeholder="Your name" value="{{ old('name') }}">
                    @error('name')
                    <div class="invalid-feedback">
                        {{ $message }}
                    </div>
                    @enderror
                </div>
                <div class="mb-3">
                    <label for="email" class="form-label">Email address</label>
                    <input type="email" class="form-control @error('email') is-invalid @enderror" id="email"
                           name="email" placeholder="name@example.com" value="{{ old('email') }}">
                    @error('email')
                    <div class="invalid-feedback">
                        {{ $message }}
                    </div>
                    @enderror
                </div>
                <div class="mb-3">
                    <label for="password" class="form-label">Password</label>
                    <input type="password" class="form-control @error('password') is-invalid @enderror" id="password" name="password" placeholder="password">
                    @error('password')
                    <div class="invalid-feedback">
                        {{ $message }}
                    </div>
                    @enderror
                </div>
                <div class="mb-3">
                    <label for="password_confirmation" class="form-label">Password Confirmation</label>
                    <input type="password" class="form-control @error('password_confirmation') is-invalid @enderror" id="password_confirmation" name="password_confirmation"
                           placeholder="password">
                    @error('password_confirmation')
                    <div class="invalid-feedback">
                        {{ $message }}
                    </div>
                    @enderror
                </div>
                <div class="mb-3">
                    <input type="submit" class="btn btn-primary" value="Register">
                </div>
            </form>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8"
        crossorigin="anonymous"></script>
</body>
</html>

Berikutnya, jika kita klik form yang kita buat akan menemui error seperti ini.

Membuat Autentikasi Manual di Laravel

Tentu saja karena kita belum membuat route untuk method post pada /register. Mari kita buat dengan membuat method store() pada RegisterController.

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;

class RegisterController extends Controller
{
    // ...
    
    public function store(Request $request)
    {
        $this->validate($request, [
            'email' => ['required','email', 'unique:users,email'],
            'password' => ['required', 'min:8'],
            'password_confirmation' => ['required', 'min:8', 'confirmed']
        ]);

       $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        if (Auth::attempt(['email' => $user->email, 'password' => $request->password])) {
            $request->session()->regenerate();

            return redirect()->intended('home');
        }
    }
}

Kemudian daftarkan pada routes/web.php

Route::post('/register', [\App\Http\Controllers\RegisterController::class, 'store'])->name('register');

Setelah itu bisa coba untuk melakukan proses register pada http://localhost:8000/register

Membuat Autentikasi Manual di Laravel

Setelah berhasil melalui validasi maka akan bertambah satu data pada tabel users dan akan di redirect ke halaman /home yang hasilnya adalah not found karena kita belum membuat routingnya. Mari kita selesaikan dengan mudah. Buat sebuah view dengan nama home.blade.php dan isi seperti ini.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">
    <title>Home</title>
</head>
<body>
    <div class="container text-center pt-4">
        Selamat Datang {{ auth()->user()->name }}
    </div>
</body>
</html>

Daftarkan ke routes/web.php

Route::view('/home', 'home')->name('home');

Oke, kalau di reload akan muncul halaman sederhana yang menyapa user yang sedang terautentikasi, sementara kita biarkan seperti itu dulu.

Membuat Fungsi Logout

Oke, tidak seperti kebanyakan tutorial yang akan membuat halaman login setelah halaman register sudah selesai, kita akan buat fungsi logoutnya dulu dengan sederhana biar kita bisa logout dulu dan bikin fungsi loginnya ya :D. Kita buat fungsinya langsung di routes/web.php

Route::post('/logout', function () {
    auth()->logout();
    request()->session()->invalidate();
    request()->session()->regenerateToken();

    return redirect('/');
})->name('logout');

Kemudian kita ubah file tampilan home.blade.php

<div class="container text-center pt-4">
    Selamat Datang {{ auth()->user()->name }}
    <div class="div">
        <form action="{{ route('logout') }}" method="post">
            @csrf
            <input type="submit" class="btn btn-danger" value="Logout">
        </form>
    </div>
</div>

Tampilan yang akan kita dapatkan kurang lebih seperti ini, bisa dicoba untuk pencet tombolnya harusnya sudah oke ya karena saya coba udah oke :p.

Tampilan home dengan Logout

Membuat Fungsi Login

Setelah membuat fungsi register dan logout, tentu saja kita butuh fungsi untuk login user. Mari kita mulai dengan membuat controllernya dulu.

php artisan make:controller LoginController

Setelah berhasil membuat controllernya, kita buat sebuah fungsi untuk menampilkan halaman login.

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class LoginController extends Controller
{
    public function login()
    {
        return view('auth.login');
    }

   // ....
}

Jangan lupa buat file viewnya ya, buat di auth/login.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">
    <title>Login</title>
</head>
<body>
<div class="container-sm">
    <div class="card">
        <div class="card-body">
            <form action="{{ route('login') }}" method="post">
                @csrf
                <div class="mb-3">
                    <label for="email" class="form-label">Email address</label>
                    <input type="email" class="form-control @error('email') is-invalid @enderror" id="email"
                           name="email" placeholder="name@example.com" value="{{ old('email') }}">
                    @error('email')
                    <div class="invalid-feedback">
                        {{ $message }}
                    </div>
                    @enderror
                </div>
                <div class="mb-3">
                    <label for="password" class="form-label">Password</label>
                    <input type="password" class="form-control @error('password') is-invalid @enderror" id="password" name="password" placeholder="password">
                    @error('password')
                    <div class="invalid-feedback">
                        {{ $message }}
                    </div>
                    @enderror
                </div>
                <div class="mb-3">
                    <input type="submit" class="btn btn-primary" value="Login">
                </div>
            </form>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8"
        crossorigin="anonymous"></script>
</body>
</html>

Berikutnya kita daftarkan ke routes/web.php

Route::get('/login', [\App\Http\Controllers\LoginController::class, 'login'])->name('login');
Tampilan Halaman Login

Selesai dengan tampilan, lanjut untuk buat fungsi login atau mengautentikasi user supaya bisa masuk atau login ke aplikasi.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    // ...

    public function authenticate(Request $request)
    {
        $credentials = $request->validate([
            'email' => ['required', 'string', 'email'],
            'password' => ['required', 'string'],
        ]);

        if (Auth::attempt($credentials)) {
            $request->session()->regenerate();

            return redirect()->intended('home');
        };

        return back()->withErrors([
            'email' => 'The provided credentials do not match our records.',
        ])->onlyInput('email');
    }
}

Selalu ingat untuk daftarkan ke routes/web.php biar ga error not found ya.

Route::post('/login', [\App\Http\Controllers\LoginController::class, 'authenicate'])->name('login');

Selesai juga serangkaian fungsi autentikasi dari register, logout dan login. Apakah sudah selesai ? sabar Kawan, tentu saja belum :P.

Menambahkan Middleware

Sementara ini, ketika kita berhasil terautentikasi baik setelah register maupun login, ketika ketika kita akses halaman /register dan /login halaman tersebut tetap bisa diakses. Harusnya itu tidak boleh terjadi, karena bagaimana ceritanya user yang sudah login mendaftarkan user baru.

Bener kan ya? kalo udah login ya ga boleh daftar lagi dong, kecuali sudah logout. Lalu gimana caranya untuk membatasinya? Tenang aja di Laravel sudah tersedia middleware yang tinggal pakai kok. Nama middlewarenya guest yang menandakan halaman / route tersebut hanya bisa diakses oleh guest atau user yang belum terautentikasi.

Kita tambahkan middleware di routes saja ya, ini cara paling saya suka dan menurut saya paling enak untuk mengatur routes dan middleware.

Route::get('/register', [\App\Http\Controllers\RegisterController::class, 'create'])->name('register')->middleware('guest');
Route::post('/register', [\App\Http\Controllers\RegisterController::class, 'store'])->name('register')->middleware('guest');
Route::get('/login', [\App\Http\Controllers\LoginController::class, 'login'])->name('login')->middleware('guest');
Route::post('/login', [\App\Http\Controllers\LoginController::class, 'authenticate'])->name('login')->middleware('guest');

Nahh, sudah beres, sekarang sebaliknya dengan route tersebut, untuk halaman /home kita ingin hanya bisa diakses oleh user yang sudah terautentikasi saja. Tenang sudah disediakan juga kok sama Laravel, baik kan? kali ini middleware yang digunakan auth. Hal ini berlaku juga untuk route /logout ya.

Route::post('/logout', function () {
    auth()->logout();
    request()->session()->invalidate();
    request()->session()->regenerateToken();

    return redirect('/');
})->name('logout')->middleware('auth');
Route::view('/home', 'home')->name('home')->middleware('auth');

Dengan seperti ini, minimal fitur autentikasi kita sudah bisa mengakomodasi kebutuhan umum untuk autentikasi ya, dari register, logout, login dan membatasi aksesnya. Semoga tutorial Membuat Autentikasi Manual di Laravel bisa bermanfaat.

Wassalamualaikum Warohmatulloh Wabarokatuh.

Hai semua, saya Amirul seorang Software Engineer, suka membuat konten pembelajaran berupa artikel, video tutorial maupun podcast

2 Comments

Tinggalkan Balasan