Login CakePHP 4 script

CakePHP 4, login biasanya menggunakan Authentication plugin. Berikut alurnya:


1. Install Authentication Plugin

Jalankan di terminal:

composer require cakephp/authentication

2. Load Plugin di Application.php

Di file src/Application.php, tambahkan:

$this->addPlugin('Authentication');

3. Middleware Authentication

Masih di Application.php, tambahkan ke middleware():

use Authentication\Middleware\AuthenticationMiddleware;

$middlewareQueue->add(new AuthenticationMiddleware($this));

4. Konfigurasi Authentication

Di src/Application.php, dalam method getAuthenticationService():

use Authentication\AuthenticationService;
use Authentication\AuthenticationServiceInterface;
use Authentication\Identifier\IdentifierInterface;
use Authentication\Middleware\AuthenticationMiddleware;
use Psr\Http\Message\ServerRequestInterface;

public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
    $service = new AuthenticationService();

    // Load authenticators
    $service->loadAuthenticator('Authentication.Session');
    $service->loadAuthenticator('Authentication.Form', [
        'fields' => [
            IdentifierInterface::CREDENTIAL_USERNAME => 'email',
            IdentifierInterface::CREDENTIAL_PASSWORD => 'password',
        ],
        'loginUrl' => '/users/login',
    ]);

    // Load identifiers
    $service->loadIdentifier('Authentication.Password', [
        'fields' => [
            IdentifierInterface::CREDENTIAL_USERNAME => 'email',
            IdentifierInterface::CREDENTIAL_PASSWORD => 'password',
        ]
    ]);

    return $service;
}

5. Buat UsersController

namespace App\Controller;

use App\Controller\AppController;

class UsersController extends AppController
{
    public function login()
    {
        $this->request->allowMethod(['get', 'post']);
        $result = $this->Authentication->getResult();

        if ($result->isValid()) {
            return $this->redirect(['controller' => 'Pages', 'action' => 'display', 'home']);
        }
        
        if ($this->request->is('post') && !$result->isValid()) {
            $this->Flash->error('Invalid email or password');
        }
    }

    public function logout()
    {
        $this->Authentication->logout();
        return $this->redirect(['controller' => 'Users', 'action' => 'login']);
    }
}

6. Buat login.php (Template)

templates/Users/login.php

<h1>Login</h1>
<?= $this->Form->create() ?>
<?= $this->Form->control('email') ?>
<?= $this->Form->control('password') ?>
<?= $this->Form->button('Login') ?>
<?= $this->Form->end() ?>

👉 Dengan setup ini, user bisa login via form dan session akan disimpan.

Mau aku bikinkan versi singkat step-by-step untuk CakePHP 3 juga (karena beda dengan CakePHP 4)?


🔑 Login di CakePHP 3


1. Load AuthComponent


Di src/Controller/AppController.php:


namespace App\Controller;


use Cake\Controller\Controller;


class AppController extends Controller

{

    public function initialize()

    {

        parent::initialize();


        $this->loadComponent('Flash');

        $this->loadComponent('Auth', [

            'authenticate' => [

                'Form' => [

                    'fields' => [

                        'username' => 'email',

                        'password' => 'password'

                    ]

                ]

            ],

            'loginAction' => [

                'controller' => 'Users',

                'action' => 'login'

            ],

            'logoutRedirect' => [

                'controller' => 'Users',

                'action' => 'login'

            ],

            'unauthorizedRedirect' => $this->referer()

        ]);

    }

}



---


2. Buat UsersController


src/Controller/UsersController.php


namespace App\Controller;


use App\Controller\AppController;


class UsersController extends AppController

{

    public function initialize()

    {

        parent::initialize();

        $this->Auth->allow(['logout']); // biar bisa logout tanpa login

    }


    public function login()

    {

        if ($this->request->is('post')) {

            $user = $this->Auth->identify();

            if ($user) {

                $this->Auth->setUser($user);

                return $this->redirect($this->Auth->redirectUrl());

            }

            $this->Flash->error('Invalid email or password, try again');

        }

    }


    public function logout()

    {

        return $this->redirect($this->Auth->logout());

    }

}



---


3. Buat View Login


src/Template/Users/login.ctp


<h1>Login</h1>

<?= $this->Form->create() ?>

<?= $this->Form->control('email') ?>

<?= $this->Form->control('password') ?>

<?= $this->Form->button('Login') ?>

<?= $this->Form->end() ?>



---


4. Tambah Hashing Password


Di UsersTable.php, biar password otomatis di-hash saat save:


use Cake\Auth\DefaultPasswordHasher;

use Cake\ORM\Entity;


class User extends Entity

{

    protected function _setPassword($password)

    {

        if (strlen($password) > 0) {

            return (new DefaultPasswordHasher)->hash($password);

        }

    }

}



---


👉 Bedanya dengan CakePHP 4 adalah:


CakePHP 3 pakai AuthComponent


CakePHP 4 pakai Authentication & Authorization plugin



berikut contoh SQL untuk tabel users yang cocok dipakai di CakePHP 3 login:



---


📂 SQL Table: users


CREATE TABLE users (

    id INT AUTO_INCREMENT PRIMARY KEY,

    name VARCHAR(100) NOT NULL,

    email VARCHAR(150) NOT NULL UNIQUE,

    password VARCHAR(255) NOT NULL,

    created DATETIME DEFAULT CURRENT_TIMESTAMP,

    modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

);



---


📌 Contoh Insert User (password sudah di-hash pakai CakePHP)


Misalnya bikin akun admin:


INSERT INTO users (name, email, password) 

VALUES ('Admin User', 'admin@example.com', 

'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi');


⚡ Password di atas adalah hash dari password (string biasa).

Jadi saat login, coba pakai:


Email: admin@example.com


Password: password




---


💡 Kalau kamu bikin user lewat Form CakePHP, password otomatis di-hash berkat kode di User Entity tadi. Jadi cukup save plain password, CakePHP yang urus hash-nya.



---


Mau aku bikinkan juga CRUD sederhana untuk Users biar kamu bisa tambah user lewat form, bukan lewat SQL manual?


Langkah Buat CRUD Users


1. Generate Scaffold pakai Bake (opsional, biar cepat)


Di terminal:


bin/cake bake all Users


Perintah ini otomatis generate:


UsersController.php


Model (UsersTable.php, User.php)


Views (index.ctp, add.ctp, edit.ctp, view.ctp)




---


2. UsersController (manual versi sederhana)


Kalau mau tulis manual, contoh minimalisnya:


namespace App\Controller;


use App\Controller\AppController;


class UsersController extends AppController

{

    public function index()

    {

        $users = $this->paginate($this->Users);

        $this->set(compact('users'));

    }


    public function view($id = null)

    {

        $user = $this->Users->get($id);

        $this->set(compact('user'));

    }


    public function add()

    {

        $user = $this->Users->newEntity();

        if ($this->request->is('post')) {

            $user = $this->Users->patchEntity($user, $this->request->getData());

            if ($this->Users->save($user)) {

                $this->Flash->success('User berhasil ditambahkan.');

                return $this->redirect(['action' => 'index']);

            }

            $this->Flash->error('Gagal menambahkan user.');

        }

        $this->set(compact('user'));

    }


    public function edit($id = null)

    {

        $user = $this->Users->get($id);

        if ($this->request->is(['patch', 'post', 'put'])) {

            $user = $this->Users->patchEntity($user, $this->request->getData());

            if ($this->Users->save($user)) {

                $this->Flash->success('User berhasil diupdate.');

                return $this->redirect(['action' => 'index']);

            }

            $this->Flash->error('Gagal update user.');

        }

        $this->set(compact('user'));

    }


    public function delete($id = null)

    {

        $this->request->allowMethod(['post', 'delete']);

        $user = $this->Users->get($id);

        if ($this->Users->delete($user)) {

            $this->Flash->success('User berhasil dihapus.');

        } else {

            $this->Flash->error('Gagal hapus user.');

        }

        return $this->redirect(['action' => 'index']);

    }

}



---


3. Views (contoh add.ctp)


src/Template/Users/add.ctp


<h1>Tambah User</h1>

<?= $this->Form->create($user) ?>

<?= $this->Form->control('name') ?>

<?= $this->Form->control('email') ?>

<?= $this->Form->control('password') ?>

<?= $this->Form->button('Simpan') ?>

<?= $this->Form->end() ?>


edit.ctp mirip, cuma judulnya ganti "Edit User".

index.ctp bisa buat tabel daftar user dengan link Edit/Delete.



---


4. Auto Hash Password


Pastikan di User.php (Entity) ada:


use Cake\Auth\DefaultPasswordHasher;

use Cake\ORM\Entity;


class User extends Entity

{

    protected function _setPassword($password)

    {

        if (strlen($password) > 0) {

            return (new DefaultPasswordHasher)->hash($password);

        }

    }

}


Dengan ini, password selalu di-hash otomatis saat simpan. ✅



---


👉 Jadi sekarang kamu bisa:


Tambah user dari form (/users/add)


Edit user (/users/edit/1)


Delete user (/users/delete/1)


Login pakai user yang dibuat




---


Mau aku bikinkan juga contoh tampilan index.ctp biar bisa langsung lihat daftar user dengan tombol edit & delete?


Aku bikinkan contoh view index.ctp untuk daftar user, lengkap dengan tombol View, Edit, Delete.



---


📂 src/Template/Users/index.ctp


<h1>Daftar User</h1>


<p><?= $this->Html->link('Tambah User', ['action' => 'add'], ['class' => 'button']) ?></p>


<table>

    <thead>

        <tr>

            <th>ID</th>

            <th>Nama</th>

            <th>Email</th>

            <th>Dibuat</th>

            <th>Diubah</th>

            <th>Aksi</th>

        </tr>

    </thead>

    <tbody>

        <?php foreach ($users as $user): ?>

        <tr>

            <td><?= h($user->id) ?></td>

            <td><?= h($user->name) ?></td>

            <td><?= h($user->email) ?></td>

            <td><?= h($user->created) ?></td>

            <td><?= h($user->modified) ?></td>

            <td>

                <?= $this->Html->link('Lihat', ['action' => 'view', $user->id]) ?> |

                <?= $this->Html->link('Edit', ['action' => 'edit', $user->id]) ?> |

                <?= $this->Form->postLink('Hapus', 

                        ['action' => 'delete', $user->id], 

                        ['confirm' => 'Yakin ingin hapus user ini?']) ?>

            </td>

        </tr>

        <?php endforeach; ?>

    </tbody>

</table>



---


✨ Hasilnya


Menampilkan daftar user dari database


Ada tombol Tambah User di atas


Kolom aksi ada link Lihat, Edit, dan Hapus (dengan konfirmasi)




---


💡 Kalau mau lebih rapih, bisa kasih sedikit CSS styling atau pakai Bootstrap.


Mau aku tambahin versi pakai Bootstrap table biar tampilan lebih modern?

aku bikinkan versi Bootstrap biar tabelnya lebih modern dan rapi.



---


📂 src/Template/Users/index.ctp (Bootstrap version)


<div class="container mt-4">

    <div class="d-flex justify-content-between align-items-center mb-3">

        <h1>Daftar User</h1>

        <?= $this->Html->link('Tambah User', ['action' => 'add'], ['class' => 'btn btn-primary']) ?>

    </div>


    <table class="table table-striped table-bordered table-hover">

        <thead class="thead-dark">

            <tr>

                <th>ID</th>

                <th>Nama</th>

                <th>Email</th>

                <th>Dibuat</th>

                <th>Diubah</th>

                <th class="text-center">Aksi</th>

            </tr>

        </thead>

        <tbody>

            <?php foreach ($users as $user): ?>

            <tr>

                <td><?= h($user->id) ?></td>

                <td><?= h($user->name) ?></td>

                <td><?= h($user->email) ?></td>

                <td><?= h($user->created) ?></td>

                <td><?= h($user->modified) ?></td>

                <td class="text-center">

                    <?= $this->Html->link('Lihat', ['action' => 'view', $user->id], ['class' => 'btn btn-sm btn-info']) ?>

                    <?= $this->Html->link('Edit', ['action' => 'edit', $user->id], ['class' => 'btn btn-sm btn-warning']) ?>

                    <?= $this->Form->postLink('Hapus', 

                            ['action' => 'delete', $user->id], 

                            ['confirm' => 'Yakin ingin hapus user ini?', 'class' => 'btn btn-sm btn-danger']) ?>

                </td>

            </tr>

            <?php endforeach; ?>

        </tbody>

    </table>

</div>



---


✨ Hasil Tampilan


Judul & tombol "Tambah User" ada di atas, rapi di kanan-kiri


Tabel pakai striped + hover effect


Tombol aksi (Lihat, Edit, Hapus) pakai warna berbeda (Info, Warning, Danger)


Tampilan otomatis responsif kalau Bootstrap sudah di-load




---


⚡ Supaya ini bekerja, pastikan Bootstrap CSS sudah dimasukkan, misalnya di src/Template/Layout/default.ctp:


<?= $this->Html->css('https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css') ?>



---


Mau aku bikinkan juga versi form login (login.ctp) pakai Bootstrap biar lebih cantik?

Aku bikinkan contoh view index.ctp untuk daftar user, lengkap dengan tombol View, Edit, Delete.


---

📂 src/Template/Users/index.ctp

<h1>Daftar User</h1>

<p><?= $this->Html->link('Tambah User', ['action' => 'add'], ['class' => 'button']) ?></p>

<table>
    <thead>
        <tr>
            <th>ID</th>
            <th>Nama</th>
            <th>Email</th>
            <th>Dibuat</th>
            <th>Diubah</th>
            <th>Aksi</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($users as $user): ?>
        <tr>
            <td><?= h($user->id) ?></td>
            <td><?= h($user->name) ?></td>
            <td><?= h($user->email) ?></td>
            <td><?= h($user->created) ?></td>
            <td><?= h($user->modified) ?></td>
            <td>
                <?= $this->Html->link('Lihat', ['action' => 'view', $user->id]) ?> |
                <?= $this->Html->link('Edit', ['action' => 'edit', $user->id]) ?> |
                <?= $this->Form->postLink('Hapus', 
                        ['action' => 'delete', $user->id], 
                        ['confirm' => 'Yakin ingin hapus user ini?']) ?>
            </td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>


---

✨ Hasilnya

Menampilkan daftar user dari database

Ada tombol Tambah User di atas

Kolom aksi ada link Lihat, Edit, dan Hapus (dengan konfirmasi)



---

💡 Kalau mau lebih rapih, bisa kasih sedikit CSS styling atau pakai Bootstrap.

Mau aku tambahin versi pakai Bootstrap table biar tampilan lebih modern?

Biar seragam dengan login, aku bikinkan form register (add.ctp) pakai Bootstrap.


---

📂 src/Template/Users/add.ctp (Bootstrap version)

<div class="container d-flex justify-content-center align-items-center" style="min-height: 100vh;">
    <div class="card shadow-lg p-4" style="width: 500px;">
        <h2 class="text-center mb-4">Register</h2>
        
        <?= $this->Form->create($user) ?>
            <div class="form-group">
                <?= $this->Form->control('name', [
                    'label' => 'Nama Lengkap',
                    'class' => 'form-control',
                    'required' => true
                ]) ?>
            </div>
            <div class="form-group">
                <?= $this->Form->control('email', [
                    'label' => 'Email',
                    'class' => 'form-control',
                    'required' => true
                ]) ?>
            </div>
            <div class="form-group">
                <?= $this->Form->control('password', [
                    'label' => 'Password',
                    'class' => 'form-control',
                    'required' => true
                ]) ?>
            </div>
            <div class="d-grid gap-2">
                <?= $this->Form->button('Daftar', ['class' => 'btn btn-success btn-block']) ?>
            </div>
        <?= $this->Form->end() ?>

        <div class="mt-3 text-center">
            <small class="text-muted">Sudah punya akun? 
                <?= $this->Html->link('Login di sini', ['action' => 'login']) ?>
            </small>
        </div>
    </div>
</div>


---

✨ Hasil Tampilan

Card form register di tengah layar, sama gaya dengan login

Field: Nama, Email, Password

Tombol register hijau (btn-success)

Ada link ke halaman Login di bawah form



---

⚡ Dengan ini, kamu punya:

Login → login.ctp (card biru)

Register → add.ctp (card hijau)

Users CRUD → index.ctp, edit.ctp, dll (Bootstrap table)



---

Mau aku bikinkan juga form edit user (edit.ctp) versi Bootstrap, biar CRUD user kamu konsisten semua UI-nya?

Oke lanjut! 😎 Biar konsisten dengan login & register, aku bikinkan form edit user (edit.ctp) pakai Bootstrap.


---

📂 src/Template/Users/edit.ctp (Bootstrap version)

<div class="container d-flex justify-content-center align-items-center" style="min-height: 100vh;">
    <div class="card shadow-lg p-4" style="width: 500px;">
        <h2 class="text-center mb-4">Edit User</h2>
        
        <?= $this->Form->create($user) ?>
            <div class="form-group">
                <?= $this->Form->control('name', [
                    'label' => 'Nama Lengkap',
                    'class' => 'form-control',
                    'required' => true,
                    'value' => $user->name
                ]) ?>
            </div>
            <div class="form-group">
                <?= $this->Form->control('email', [
                    'label' => 'Email',
                    'class' => 'form-control',
                    'required' => true,
                    'value' => $user->email
                ]) ?>
            </div>
            <div class="form-group">
                <?= $this->Form->control('password', [
                    'label' => 'Password (isi jika ingin ubah)',
                    'class' => 'form-control',
                    'type' => 'password'
                ]) ?>
            </div>
            <div class="d-grid gap-2">
                <?= $this->Form->button('Update', ['class' => 'btn btn-warning btn-block']) ?>
            </div>
        <?= $this->Form->end() ?>

        <div class="mt-3 text-center">
            <small class="text-muted">
                <?= $this->Html->link('Kembali ke daftar user', ['action' => 'index']) ?>
            </small>
        </div>
    </div>
</div>


---

✨ Hasil Tampilan

Card form edit di tengah layar (500px, sama dengan register)

Field otomatis terisi dengan data user yang dipilih

Password kosong → hanya update kalau diisi

Tombol update warna kuning (btn-warning)

Link kembali ke daftar user



---

⚡ Jadi sekarang kamu punya UI Bootstrap lengkap untuk:

Login (login.ctp) ✅

Register (add.ctp) ✅

Edit User (edit.ctp) ✅

Index User (daftar + CRUD) (index.ctp) ✅



---

Mau aku bikinkan juga detail user (view.ctp) versi Bootstrap, biar saat klik "Lihat" di daftar user tampilannya rapih?

Sip, kita lengkapi CRUD-nya! 🚀
Sekarang aku bikinkan tampilan detail user (view.ctp) versi Bootstrap biar rapi saat klik tombol Lihat di daftar user.


---

📂 src/Template/Users/view.ctp (Bootstrap version)

<div class="container d-flex justify-content-center align-items-center" style="min-height: 100vh;">
    <div class="card shadow-lg p-4" style="width: 500px;">
        <h2 class="text-center mb-4">Detail User</h2>
        
        <table class="table table-bordered">
            <tr>
                <th>ID</th>
                <td><?= h($user->id) ?></td>
            </tr>
            <tr>
                <th>Nama</th>
                <td><?= h($user->name) ?></td>
            </tr>
            <tr>
                <th>Email</th>
                <td><?= h($user->email) ?></td>
            </tr>
            <tr>
                <th>Dibuat</th>
                <td><?= h($user->created) ?></td>
            </tr>
            <tr>
                <th>Diubah</th>
                <td><?= h($user->modified) ?></td>
            </tr>
        </table>

        <div class="d-flex justify-content-between mt-3">
            <?= $this->Html->link('Kembali', ['action' => 'index'], ['class' => 'btn btn-secondary']) ?>
            <div>
                <?= $this->Html->link('Edit', ['action' => 'edit', $user->id], ['class' => 'btn btn-warning']) ?>
                <?= $this->Form->postLink('Hapus', 
                        ['action' => 'delete', $user->id], 
                        ['confirm' => 'Yakin ingin hapus user ini?', 'class' => 'btn btn-danger']) ?>
            </div>
        </div>
    </div>
</div>


---

✨ Hasil Tampilan

Card berisi tabel detail user

Informasi: ID, Nama, Email, Dibuat, Diubah

Tombol Kembali (abu-abu), Edit (kuning), dan Hapus (merah) di bawah



---

⚡ Dengan ini, seluruh CRUD Users kamu sudah full Bootstrap:

Login (login.ctp)

Register (add.ctp)

Edit (edit.ctp)

Index (index.ctp)

View (view.ctp)



---

Mau aku sekalian bikinkan tampilan navbar (menu) di default.ctp pakai Bootstrap, biar ada link ke Users dan Logout kalau sudah login?

Kita bikin navbar Bootstrap di default.ctp biar aplikasi kelihatan profesional. Navbar ini bisa tampilkan link ke Users, Login, Logout, tergantung status login.


---

📂 src/Template/Layout/default.ctp (contoh dengan Navbar Bootstrap)

<!DOCTYPE html>
<html>
<head>
    <?= $this->Html->charset() ?>
    <title><?= $this->fetch('title') ?></title>
    <?= $this->Html->css('https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css') ?>
    <?= $this->Html->script('https://code.jquery.com/jquery-3.6.0.min.js') ?>
    <?= $this->Html->script('https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js') ?>
    <?= $this->fetch('meta') ?>
    <?= $this->fetch('css') ?>
    <?= $this->fetch('script') ?>
</head>
<body>
    <!-- Navbar -->
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="<?= $this->Url->build('/') ?>">MyApp</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav mr-auto">
                <?php if ($this->request->getSession()->check('Auth.User')): ?>
                    <li class="nav-item">
                        <?= $this->Html->link('Users', ['controller' => 'Users', 'action' => 'index'], ['class' => 'nav-link']) ?>
                    </li>
                <?php endif; ?>
            </ul>

            <ul class="navbar-nav">
                <?php if ($this->request->getSession()->check('Auth.User')): ?>
                    <li class="nav-item">
                        <span class="navbar-text text-light mr-3">
                            Halo, <?= h($this->request->getSession()->read('Auth.User.name')) ?>
                        </span>
                    </li>
                    <li class="nav-item">
                        <?= $this->Html->link('Logout', ['controller' => 'Users', 'action' => 'logout'], ['class' => 'nav-link']) ?>
                    </li>
                <?php else: ?>
                    <li class="nav-item">
                        <?= $this->Html->link('Login', ['controller' => 'Users', 'action' => 'login'], ['class' => 'nav-link']) ?>
                    </li>
                    <li class="nav-item">
                        <?= $this->Html->link('Register', ['controller' => 'Users', 'action' => 'add'], ['class' => 'nav-link']) ?>
                    </li>
                <?php endif; ?>
            </ul>
        </div>
    </nav>

    <!-- Main content -->
    <main class="container mt-4">
        <?= $this->Flash->render() ?>
        <?= $this->fetch('content') ?>
    </main>
</body>
</html>


---

✨ Fitur Navbar

Brand (MyApp) di kiri → link ke home (/)

Kalau sudah login:

Tampil link Users

Muncul sapaan Halo, [Nama User]

Tombol Logout


Kalau belum login:

Tampil link Login

Tampil link Register




---

⚡ Dengan ini aplikasi kamu sudah:

CRUD Users full Bootstrap

Form Login & Register rapi

Navbar dinamis sesuai status login



---

Mau aku bikinkan juga redirect otomatis ke halaman login kalau belum login (proteksi route pakai beforeFilter)?

Oke, kita amankan aplikasi 💪.
Di CakePHP 3, biasanya proteksi halaman dilakukan dengan beforeFilter() di AppController. Jadi hanya halaman tertentu (misalnya login & register) yang bisa diakses tanpa login, sisanya otomatis redirect ke login.


---

📂 src/Controller/AppController.php

Tambahkan beforeFilter() seperti ini:

namespace App\Controller;

use Cake\Controller\Controller;

class AppController extends Controller
{
    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('Flash');
        $this->loadComponent('Auth', [
            'authenticate' => [
                'Form' => [
                    'fields' => ['username' => 'email', 'password' => 'password']
                ]
            ],
            'loginAction' => [
                'controller' => 'Users',
                'action' => 'login'
            ],
            'loginRedirect' => [
                'controller' => 'Users',
                'action' => 'index'
            ],
            'logoutRedirect' => [
                'controller' => 'Users',
                'action' => 'login'
            ],
            'unauthorizedRedirect' => [
                'controller' => 'Users',
                'action' => 'login'
            ],
            'authError' => 'Anda harus login untuk mengakses halaman ini.'
        ]);
    }

    public function beforeFilter(\Cake\Event\Event $event)
    {
        // Izinkan halaman tanpa login
        $this->Auth->allow(['display']); // biasanya untuk home page
    }
}


---

📂 src/Controller/UsersController.php

Supaya login & register bisa diakses tanpa login, tambahkan:

public function initialize()
{
    parent::initialize();
    $this->Auth->allow(['login', 'add']); 
}


---

⚡ Alurnya

Kalau belum login dan coba buka /users/index → otomatis redirect ke /users/login

Halaman login (/users/login) & register (/users/add) bisa diakses bebas

Setelah login berhasil → redirect ke /users/index (atau bisa diarahkan ke halaman lain sesuai kebutuhan)



---

🔥 Dengan ini, aplikasi kamu sudah:

CRUD full Bootstrap

Login & Register modern

Navbar dinamis

Proteksi route dengan Auth (akses aman)



---

Mau aku bikinkan juga role-based access control (RBAC) sederhana (misalnya admin bisa manage users, user biasa hanya bisa edit profil sendiri)?


Oke, sekarang kita tambahin Role-Based Access Control (RBAC) biar aplikasi lebih aman dan fleksibel 🔐.
Dengan RBAC, kita bisa bedain admin dan user biasa:

Admin → bisa CRUD semua user

User biasa → hanya bisa edit profil sendiri



---

1. Update Tabel users

Tambahin kolom role:

ALTER TABLE users ADD role ENUM('admin','user') NOT NULL DEFAULT 'user';


---

2. Saat Register (add user), default role = user

Di UsersController@add:

public function add()
{
    $user = $this->Users->newEntity();
    if ($this->request->is('post')) {
        $user = $this->Users->patchEntity($user, $this->request->getData());
        $user->role = 'user'; // default user biasa
        if ($this->Users->save($user)) {
            $this->Flash->success('User berhasil didaftarkan.');
            return $this->redirect(['action' => 'login']);
        }
        $this->Flash->error('Gagal mendaftar, coba lagi.');
    }
    $this->set(compact('user'));
}


---

3. Buat Middleware Proteksi dengan isAuthorized

Di AppController.php:

public function isAuthorized($user)
{
    // Admin boleh akses semua
    if (isset($user['role']) && $user['role'] === 'admin') {
        return true;
    }

    // Default deny
    return false;
}


---

4. Batasi Akses di UsersController

Override isAuthorized khusus UsersController:

public function isAuthorized($user)
{
    // Semua user boleh edit profil sendiri
    if ($this->request->getParam('action') === 'edit') {
        $id = (int)$this->request->getParam('pass.0');
        return $id === $user['id']; // hanya boleh edit profil sendiri
    }

    // Tambahan aturan: hanya admin bisa index, add, delete
    if (in_array($this->request->getParam('action'), ['index', 'delete', 'add'])) {
        return $user['role'] === 'admin';
    }

    return parent::isAuthorized($user);
}


---

5. Navbar Menyesuaikan Role

Di default.ctp, ubah menu Users jadi hanya muncul untuk admin:

<?php if ($this->request->getSession()->read('Auth.User.role') === 'admin'): ?>
    <li class="nav-item">
        <?= $this->Html->link('Users', ['controller' => 'Users', 'action' => 'index'], ['class' => 'nav-link']) ?>
    </li>
<?php endif; ?>


---

⚡ Alurnya

Kalau login sebagai admin → bisa manage semua user

Kalau login sebagai user biasa → hanya bisa:

Edit profilnya sendiri

Tidak bisa buka /users/index atau /users/delete/:id


Navbar otomatis hide menu "Users" untuk user biasa



---

🔥 Dengan ini aplikasi kamu sudah:

CRUD full Bootstrap ✅

Login & Register ✅

Navbar dinamis ✅

Proteksi route ✅

RBAC (role-based access control) ✅



---

Mau aku bikinkan juga contoh seed SQL buat 1 admin + 1 user, biar bisa langsung coba RBAC?

Sip! 🔥 Aku bikinkan contoh seed SQL untuk bikin 1 admin + 1 user, jadi kamu bisa langsung tes RBAC.


---

📂 SQL Insert Admin & User

INSERT INTO users (name, email, password, role, created, modified) VALUES
-- Admin user (email: admin@example.com, password: admin123)
('Super Admin', 'admin@example.com', 
'$2y$10$7QKnkL9A9TtyY1AQMYl66efzCFPveJt6Gz1ScMAVgi9ja2bJxub4O', 
'admin', NOW(), NOW()),

-- Regular user (email: user@example.com, password: user123)
('Regular User', 'user@example.com', 
'$2y$10$eYlvfTnQVE1kBZvN7FlBjeNTi2p/8KJ30WDKYgk9zLMqDfeTLEqYq', 
'user', NOW(), NOW());


---

🔑 Credentials untuk login

Admin

Email: admin@example.com

Password: admin123


User biasa

Email: user@example.com

Password: user123




---

⚡ Efek RBAC

Kalau login sebagai admin → bisa CRUD semua user (akses /users/index, delete, dll).

Kalau login sebagai user biasa → hanya bisa edit profil sendiri, tidak bisa buka halaman daftar user.

Navbar "Users" hanya muncul kalau login sebagai admin.



---

🔥 Dengan ini kamu bisa langsung uji coba sistem login + RBAC di aplikasi CakePHP 3 kamu.

Mau aku bikinkan juga middleware flash message pakai Bootstrap alert biar notifikasi sukses/gagal login/register lebih rapi?






Comments