Tutorial Laravel & ReactJS #3: Autentikasi Multi-Level dengan Sanctum

Tutorial #3: Autentikasi Multi-Level (Admin & Petugas) dengan Laravel Sanctum

Halo penjaga pintu aplikasi bank! Hari ini kita akan membuat sistem login dan registrasi yang bisa bedain Admin, Petugas, dan Nasabah. Plus kita pasang Sanctum sebagai satpam API kita. Siap? Awas jangan sampai salah kasih kunci! 

😂 Joke biar melek: "Kenapa Laravel pakai Sanctum? Soalnya kalau pakai satpam biasa, takut kena bug (serangga)!" 🐞

Apa yang akan kita lakukan?

  • ✅ Install Laravel Sanctum (satpam API).
  • ✅ Siapkan model User supaya bisa kasih token.
  • ✅ Buat fitur register (buat nasabah baru).
  • ✅ Buat fitur login (buat semua role).
  • ✅ Buat fitur logout (hapus token).
  • ✅ Buat middleware khusus untuk role Admin dan Petugas.
  • ✅ Uji coba dengan endpoint sederhana.

Langkah 1: Install Laravel Sanctum

Buka terminal di folder bank-backend, jalankan perintah ini:

composer require laravel/sanctum

Setelah selesai, publish file konfigurasi dan migrasi Sanctum:

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

Ini akan membuat file migration baru untuk tabel personal_access_tokens. Jangan lupa jalankan migrasi:

php artisan migrate

Kalau sukses, sekarang kita punya tempat buat nyimpen token-token yang kita kasih ke pengguna.

💡 Sanctum itu apa sih? Sanctum kayak gantungan kunci digital. Setiap kali pengguna login, kita kasih dia sebuah token (kunci). Token ini harus dibawa setiap kali pengguna minta data ke API. Jadi API tahu kalau yang minta adalah pengguna yang sah.

Langkah 2: Konfigurasi Model User

Buka file app/Models/User.php. Kita perlu menambahkan trait HasApiTokens agar model User bisa mengeluarkan token. Ubah bagian atas model menjadi:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;  // <-- tambahkan baris ini

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;   // <-- tambahkan HasApiTokens di sini

    // ... sisanya tetap
}

Dengan ini, setiap instance User bisa memanggil $user->createToken() dan $user->tokens().

Langkah 3: Membuat Controller Auth

Buat controller khusus untuk autentikasi:

php artisan make:controller Api/AuthController

File akan muncul di app/Http/Controllers/Api/AuthController.php. Buka dan isi dengan kode berikut:

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Account;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

class AuthController extends Controller
{
    // REGISTER (khusus untuk nasabah baru)
    public function register(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]);

        // Buat user dengan role_id = 3 (Nasabah)
        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
            'role_id' => 3,
        ]);

        // Buatkan rekening tabungan (account) otomatis
        $accountNumber = 'REK' . time() . rand(100, 999);
        Account::create([
            'user_id' => $user->id,
            'account_number' => $accountNumber,
            'balance' => 0,
        ]);

        // Buat token untuk user yang baru daftar
        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'message' => 'Registrasi berhasil, selamat menabung!',
            'user' => $user,
            'token' => $token,
        ], 201);
    }

    // LOGIN (untuk semua role)
    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        $user = User::with('role')->where('email', $request->email)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            throw ValidationException::withMessages([
                'email' => ['Email atau password salah.'],
            ]);
        }

        // Hapus token lama biar nggak numpuk (opsional)
        $user->tokens()->delete();

        // Buat token baru
        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'message' => 'Login sukses!',
            'user' => [
                'id' => $user->id,
                'name' => $user->name,
                'email' => $user->email,
                'role' => $user->role->name, // kita kirim nama role
            ],
            'token' => $token,
        ]);
    }

    // LOGOUT (hapus token yang dipakai)
    public function logout(Request $request)
    {
        $request->user()->currentAccessToken()->delete();

        return response()->json([
            'message' => 'Logout berhasil, sampai jumpa!',
        ]);
    }
}

Penjelasan singkat:

  • register: buat user role nasabah, sekalian bikin nomor rekening unik.
  • login: cek email dan password, kalau cocok kasih token baru.
  • logout: hapus token yang lagi dipakai.

Langkah 4: Middleware untuk Role (Admin & Petugas)

Kita perlu memastikan hanya admin yang bisa akses tertentu, hanya petugas yang bisa akses lainnya. Buat middleware khusus.

php artisan make:middleware IsAdmin

Buka file app/Http/Middleware/IsAdmin.php, isi method handle:

public function handle(Request $request, Closure $next)
{
    if ($request->user() && $request->user()->role_id == 1) { // 1 = Admin
        return $next($request);
    }
    return response()->json(['message' => 'Akses ditolak, kamu bukan admin'], 403);
}

Buat juga middleware IsPetugas:

php artisan make:middleware IsPetugas

Isi dengan:

public function handle(Request $request, Closure $next)
{
    if ($request->user() && $request->user()->role_id == 2) { // 2 = Petugas
        return $next($request);
    }
    return response()->json(['message' => 'Akses ditolak, kamu bukan petugas'], 403);
}

Setelah itu, daftarkan middleware ini di app/Http/Kernel.php. Cari array $routeMiddleware lalu tambahkan:

'isAdmin' => \App\Http\Middleware\IsAdmin::class,
'isPetugas' => \App\Http\Middleware\IsPetugas::class,

Langkah 5: Membuat Route API

Buka routes/api.php, bersihkan isinya dan tulis route berikut:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\AuthController;

// Route publik (tanpa autentikasi)
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);

// Route yang butuh token (sudah login)
Route::middleware('auth:sanctum')->group(function () {
    Route::post('/logout', [AuthController::class, 'logout']);

    // Contoh route untuk mendapatkan data user yang sedang login
    Route::get('/user', function (Request $request) {
        return $request->user()->load('role', 'account');
    });

    // Route khusus admin
    Route::middleware('isAdmin')->group(function () {
        Route::get('/admin/dashboard', function () {
            return response()->json(['message' => 'Selamat datang Admin!']);
        });
        // nanti tambah route CRUD user dll
    });

    // Route khusus petugas
    Route::middleware('isPetugas')->group(function () {
        Route::get('/petugas/dashboard', function () {
            return response()->json(['message' => 'Selamat datang Petugas!']);
        });
        // nanti route transaksi nabung/tarik
    });

    // Route untuk nasabah (semua yang login bisa akses)
    Route::get('/nasabah/saldo', function (Request $request) {
        $account = $request->user()->account;
        return response()->json([
            'saldo' => $account ? $account->balance : 0,
            'no_rekening' => $account->account_number ?? null,
        ]);
    });
});
😆 Istirahat sejenak: "Kenapa middleware suka di tengah? Karena dia selalu handle (menangani) request sebelum sampai ke tujuan!" 🤲

🧪 Langkah 6: Uji Coba dengan Postman atau Termux

Pastikan server Laravel jalan (php artisan serve). Buka Postman atau aplikasi tes API lainnya.

EndpointMethodBody (form-data/json)
/api/registerPOSTname, email, password, password_confirmation
/api/loginPOSTemail, password
/api/logoutPOSTHeader: Authorization Bearer {token}
/api/userGETBearer token

Coba registrasi: Kirim data ke http://127.0.0.1:8000/api/register. Kalau berhasil, akan dapat token.

Coba login: Pakai email dan password yang tadi. Dapat token lagi.

Coba akses /api/user dengan menyertakan token di header (Authorization: Bearer <token>). Harusnya muncul data user plus role dan rekening.

Coba akses route khusus role: Misal login sebagai admin (role_id=1), coba GET /api/admin/dashboard dengan token. Kalau berhasil, dapat pesan selamat datang. Kalau login sebagai nasabah, akan ditolak (403).

🧠 Catatan Penting: Token ini ibarat kunci kamar. Jangan sampai hilang atau diberikan ke orang lain. Di React nanti, kita simpan token di localStorage atau cookie, lalu dikirim setiap request.

Bonus: Membuat Data Dummy Admin & Petugas

Kita perlu punya akun admin dan petugas untuk testing. Bisa buat via seeder atau tinker. Pakai tinker:

php artisan tinker

Lalu ketik:

$user = new App\Models\User();
$user->name = 'Admin Bank';
$user->email = 'admin@bank.com';
$user->password = Hash::make('rahasia123');
$user->role_id = 1; // admin
$user->save();

$user2 = new App\Models\User();
$user2->name = 'Petugas Andi';
$user2->email = 'petugas@bank.com';
$user2->password = Hash::make('rahasia123');
$user2->role_id = 2; // petugas
$user2->save();

Sekarang kita punya dua pengguna untuk testing.

Kesimpulan

  • ✅ Sanctum terpasang dan siap jaga API.
  • ✅ Register, login, logout berfungsi.
  • ✅ Middleware role (isAdmin, isPetugas) sudah aktif.
  • ✅ Route dibedakan berdasarkan role.

Di tutorial selanjutnya (#4: API Manajemen Pengguna (Admin & Petugas)) kita akan membuat fitur CRUD untuk data user oleh admin, serta manajemen petugas. Jangan kemana-mana, siapkan camilan dan minuman manis biar kode makin manis! 

Lebih baru Lebih lama

نموذج الاتصال