Modul 04: Modul Autentikasi (Login & Register)

Modul 04: Modul Autentikasi (Login & Register)

Berikut adalah seluruh berkas kode program aktual yang digunakan dalam aplikasi SIPAS tanpa potongan atau placeholder. Kode dapat dipelajari dan diketikkan langsung pada Sublime Text 3.

1

Model Pengguna (User_model.php)

Lokasi Berkas: application/models/User_model.php

application/models/User_model.php PHP
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * User_model
 * Model untuk pengelolaan data pengguna (Admin & Siswa)
 */
class User_model extends CI_Model {

    private $table = 'users';

    public function __construct() {
        parent::__construct();
    }

    /**
     * Mengambil semua data user dengan role tertentu (default: user/siswa)
     */
    public function get_all($role = 'user', $limit = NULL, $offset = NULL) {
        $this->db->where('role', $role);
        $this->db->order_by('created_at', 'DESC');
        if ($limit !== NULL) {
            $this->db->limit($limit, $offset);
        }
        return $this->db->get($this->table)->result();
    }

    /**
     * Menghitung total data user dengan filter role
     */
    public function count_all($role = 'user', $search = NULL, $status = NULL) {
        $this->db->where('role', $role);
        if (!empty($search)) {
            $this->db->group_start();
            $this->db->like('nama', $search);
            $this->db->or_like('nis', $search);
            $this->db->or_like('username', $search);
            $this->db->group_end();
        }
        if (!empty($status)) {
            $this->db->where('status', $status);
        }
        return $this->db->count_all_results($this->table);
    }

    /**
     * Pencarian user dengan pagination & filter status
     */
    public function search($role = 'user', $search = NULL, $status = NULL, $limit = 10, $offset = 0) {
        $this->db->where('role', $role);
        if (!empty($search)) {
            $this->db->group_start();
            $this->db->like('nama', $search);
            $this->db->or_like('nis', $search);
            $this->db->or_like('username', $search);
            $this->db->group_end();
        }
        if (!empty($status)) {
            $this->db->where('status', $status);
        }
        $this->db->order_by('created_at', 'DESC');
        return $this->db->get($this->table, $limit, $offset)->result();
    }

    /**
     * Mengambil data user berdasarkan ID
     */
    public function get_by_id($id) {
        return $this->db->get_where($this->table, ['id' => $id])->row();
    }

    /**
     * Mengambil data user berdasarkan username
     */
    public function get_by_username($username) {
        return $this->db->get_where($this->table, ['username' => $username])->row();
    }

    /**
     * Menambahkan user baru
     */
    public function create($data) {
        return $this->db->insert($this->table, $data);
    }

    /**
     * Memperbarui data user
     */
    public function update($id, $data) {
        $this->db->where('id', $id);
        return $this->db->update($this->table, $data);
    }

    /**
     * Menghapus data user
     */
    public function delete($id) {
        $this->db->where('id', $id);
        return $this->db->delete($this->table);
    }

    /**
     * Cek apakah user memiliki transaksi aktif yang belum dikembalikan
     */
    public function has_active_transaction($user_id) {
        $this->db->where('user_id', $user_id);
        $this->db->where('status', 'dipinjam');
        return $this->db->count_all_results('transaksi') > 0;
    }
}
💡 Catatan: Baris komentar (// atau /* */) bersifat opsional/penjelas logika. Tidak wajib diketik semua agar lebih cepat.
2

Controller Autentikasi (Auth.php)

Lokasi Berkas: application/controllers/Auth.php

application/controllers/Auth.php PHP
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Auth Controller
 * Menangani Login, Registrasi Siswa, dan Logout
 */
class Auth extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('User_model');
    }

    /**
     * Halaman Login (/login atau default /)
     */
    public function login() {
        // Jika sudah login, langsung arahkan ke dashboard masing-masing
        if (is_logged_in()) {
            if ($this->session->userdata('role') === 'admin') {
                redirect('admin/dashboard');
            } else {
                redirect('user/dashboard');
            }
        }

        // Form Validation Rules
        $this->form_validation->set_rules('username', 'Username', 'required|trim', [
            'required' => 'Username wajib diisi.'
        ]);
        $this->form_validation->set_rules('password', 'Password', 'required|trim', [
            'required' => 'Password wajib diisi.'
        ]);

        if ($this->form_validation->run() === FALSE) {
            $data['title'] = 'Masuk - SIPAS Perpustakaan';
            $this->load->view('auth/login', $data);
        } else {
            $this->_process_login();
        }
    }

    /**
     * Proses verifikasi kredensial login
     */
    private function _process_login() {
        $username = $this->input->post('username', TRUE);
        $password = $this->input->post('password', TRUE);

        $user = $this->User_model->get_by_username($username);

        // 1. Cek apakah user terdaftar
        if (!$user) {
            $this->session->set_flashdata('error', 'Username atau password salah.');
            redirect('login');
            return;
        }

        // 2. Cek status akun
        if ($user->status !== 'aktif') {
            $this->session->set_flashdata('error', 'Akun Anda sedang dinonaktifkan. Silakan hubungi petugas perpustakaan.');
            redirect('login');
            return;
        }

        // 3. Verifikasi password dengan password_verify()
        if (!password_verify($password, $user->password)) {
            $this->session->set_flashdata('error', 'Username atau password salah.');
            redirect('login');
            return;
        }

        // 4. Set Session
        $session_data = [
            'user_id'   => $user->id,
            'nama'      => $user->nama,
            'username'  => $user->username,
            'nis'       => $user->nis,
            'kelas'     => $user->kelas,
            'role'      => $user->role,
            'logged_in' => TRUE
        ];
        $this->session->set_userdata($session_data);
        $this->session->set_flashdata('success', 'Selamat datang kembali, ' . html_escape($user->nama) . '!');

        // 5. Redirect berdasarkan role
        if ($user->role === 'admin') {
            redirect('admin/dashboard');
        } else {
            redirect('user/dashboard');
        }
    }

    /**
     * Halaman Registrasi Siswa (/register)
     */
    public function register() {
        if (is_logged_in()) {
            redirect('user/dashboard');
        }

        $this->form_validation->set_rules('nama', 'Nama Lengkap', 'required|trim', [
            'required' => 'Nama lengkap wajib diisi.'
        ]);
        $this->form_validation->set_rules('nis', 'NIS', 'required|trim|is_unique[users.nis]', [
            'required' => 'NIS wajib diisi.',
            'is_unique' => 'NIS ini sudah terdaftar.'
        ]);
        $this->form_validation->set_rules('kelas', 'Kelas', 'required|trim', [
            'required' => 'Kelas wajib diisi.'
        ]);
        $this->form_validation->set_rules('username', 'Username', 'required|trim|is_unique[users.username]|min_length[3]', [
            'required' => 'Username wajib diisi.',
            'is_unique' => 'Username sudah digunakan, silakan pilih yang lain.',
            'min_length' => 'Username minimal 3 karakter.'
        ]);
        $this->form_validation->set_rules('password', 'Password', 'required|min_length[5]', [
            'required' => 'Password wajib diisi.',
            'min_length' => 'Password minimal 5 karakter.'
        ]);
        $this->form_validation->set_rules('konfirmasi_password', 'Konfirmasi Password', 'required|matches[password]', [
            'required' => 'Konfirmasi password wajib diisi.',
            'matches' => 'Konfirmasi password tidak cocok dengan password.'
        ]);

        if ($this->form_validation->run() === FALSE) {
            $data['title'] = 'Pendaftaran Anggota - SIPAS';
            $this->load->view('auth/register', $data);
        } else {
            $data_user = [
                'nama'       => $this->input->post('nama', TRUE),
                'nis'        => $this->input->post('nis', TRUE),
                'kelas'      => $this->input->post('kelas', TRUE),
                'username'   => strtolower($this->input->post('username', TRUE)),
                'password'   => password_hash($this->input->post('password'), PASSWORD_BCRYPT),
                'role'       => 'user',
                'status'     => 'aktif',
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ];

            if ($this->User_model->create($data_user)) {
                $this->session->set_flashdata('success', 'Pendaftaran berhasil. Silakan masuk dengan akun Anda.');
                redirect('login');
            } else {
                $this->session->set_flashdata('error', 'Terjadi kesalahan sistem saat mendaftar. Silakan coba lagi.');
                redirect('register');
            }
        }
    }

    /**
     * Proses Logout (/logout)
     */
    public function logout() {
        $this->session->sess_destroy();
        redirect('login');
    }
}
💡 Catatan: Baris komentar (// atau /* */) bersifat opsional/penjelas logika. Tidak wajib diketik semua agar lebih cepat.
3

View Formulir Login (login.php)

Lokasi Berkas: application/views/auth/login.php

Tampilan Halaman Login
Gambar: Pratinjau antarmuka halaman login SIPAS (/login).
application/views/auth/login.php PHP
<?php $this->load->view('layouts/header'); ?>

<div class="auth-wrapper">
    <div class="auth-card">
        <div class="text-center mb-4">
            <div class="sidebar-brand-icon mx-auto mb-2" style="width: 48px; height: 48px; font-size: 1.5rem;">
                <i class="bi bi-book-half"></i>
            </div>
            <h4 class="fw-bold text-dark mb-1">SIPAS PERPUSTAKAAN</h4>
            <p class="text-secondary small mb-0">Masuk untuk mengakses layanan perpustakaan digital</p>
        </div>

        <?php $this->load->view('layouts/flash_message'); ?>

        <form action="<?= site_url('login') ?>" method="POST" class="prevent-double-submit">
            <div class="mb-3">
                <label for="username" class="form-label">Username</label>
                <div class="input-group">
                    <span class="input-group-text bg-light text-muted border-end-0"><i class="bi bi-person"></i></span>
                    <input type="text" class="form-control border-start-0 ps-0" id="username" name="username" value="<?= set_value('username') ?>" placeholder="Masukkan username Anda" required autofocus>
                </div>
            </div>

            <div class="mb-4">
                <label for="password" class="form-label">Password</label>
                <div class="input-group">
                    <span class="input-group-text bg-light text-muted border-end-0"><i class="bi bi-lock"></i></span>
                    <input type="password" class="form-control border-start-0 ps-0" id="password" name="password" placeholder="Masukkan password" required>
                </div>
            </div>

            <button type="submit" class="btn btn-primary w-100 py-2 justify-content-center fw-semibold mb-3">
                <i class="bi bi-box-arrow-in-right"></i> MASUK
            </button>

            <div class="text-center">
                <span class="text-muted small">Belum punya akun?</span>
                <a href="<?= site_url('register') ?>" class="small fw-semibold text-decoration-none text-primary ms-1">Daftar Sekarang</a>
            </div>
        </form>
    </div>
</div>

<?php $this->load->view('layouts/footer'); ?>
💡 Catatan: Baris komentar (// atau /* */) bersifat opsional/penjelas logika. Tidak wajib diketik semua agar lebih cepat.
4

View Formulir Registrasi (register.php)

Lokasi Berkas: application/views/auth/register.php

Tampilan Halaman Registrasi
Gambar: Pratinjau antarmuka formulir registrasi anggota siswa (/register).
application/views/auth/register.php PHP
<?php $this->load->view('layouts/header'); ?>

<div class="auth-wrapper">
    <div class="auth-card auth-card-wide">
        <div class="text-center mb-4">
            <div class="sidebar-brand-icon mx-auto mb-2" style="width: 48px; height: 48px; font-size: 1.5rem;">
                <i class="bi bi-person-plus-fill"></i>
            </div>
            <h4 class="fw-bold text-dark mb-1">Daftar Akun Anggota</h4>
            <p class="text-secondary small mb-0">Lengkapi data diri untuk menjadi anggota perpustakaan digital</p>
        </div>

        <?php $this->load->view('layouts/flash_message'); ?>

        <form action="<?= site_url('register') ?>" method="POST" class="prevent-double-submit">
            <div class="mb-3">
                <label for="nama" class="form-label">Nama Lengkap</label>
                <input type="text" class="form-control" id="nama" name="nama" value="<?= set_value('nama') ?>" placeholder="Contoh: Andi Pratama" required autofocus>
            </div>

            <div class="row g-3 mb-3">
                <div class="col-md-6">
                    <label for="nis" class="form-label">NIS (Nomor Induk Siswa)</label>
                    <input type="text" class="form-control" id="nis" name="nis" value="<?= set_value('nis') ?>" placeholder="Contoh: 23001" required>
                </div>
                <div class="col-md-6">
                    <label for="kelas" class="form-label">Kelas</label>
                    <input type="text" class="form-control" id="kelas" name="kelas" value="<?= set_value('kelas') ?>" placeholder="Contoh: XII RPL 1" required>
                </div>
            </div>

            <div class="mb-3">
                <label for="username" class="form-label">Username</label>
                <input type="text" class="form-control" id="username" name="username" value="<?= set_value('username') ?>" placeholder="Pilih username unik (tanpa spasi)" required>
            </div>

            <div class="row g-3 mb-4">
                <div class="col-md-6">
                    <label for="password" class="form-label">Password</label>
                    <input type="password" class="form-control" id="password" name="password" placeholder="Minimal 5 karakter" required>
                </div>
                <div class="col-md-6">
                    <label for="konfirmasi_password" class="form-label">Konfirmasi Password</label>
                    <input type="password" class="form-control" id="konfirmasi_password" name="konfirmasi_password" placeholder="Ulangi password" required>
                </div>
            </div>

            <button type="submit" class="btn btn-primary w-100 py-2 justify-content-center fw-semibold mb-3">
                <i class="bi bi-check2-circle"></i> DAFTAR SEKARANG
            </button>

            <div class="text-center">
                <span class="text-muted small">Sudah punya akun?</span>
                <a href="<?= site_url('login') ?>" class="small fw-semibold text-decoration-none text-primary ms-1">Masuk</a>
            </div>
        </form>
    </div>
</div>

<?php $this->load->view('layouts/footer'); ?>
💡 Catatan: Baris komentar (// atau /* */) bersifat opsional/penjelas logika. Tidak wajib diketik semua agar lebih cepat.