Membuat Website dengan CodeIgniter #4

Sep 27, 2009   //   by anggie   //   CodeIgniter, PHP  //  91 Comments

Dalam seri tutorial kali ini, kita akan membuat sistem user authentification. Kita akan membahas pembuatan sistem login multi user (level) dan bagaimana mengatasi validasinya di setiap halaman-halaman penting. Sistem authentification ini sangat berguna di dalam pembuatan aplikasi web yang digunakan oleh user yang lebih dari satu. Perlu saya sampaikan disini bahwa sistem yang akan kita buat merupakan ‘basic concept’ saja. Artinya, pada kenyataannya, security perlu Anda tingkatkan.
Oke kita mulai. Hal pertama yang perlu kita siapkan adalah tabel dalam database kita. Kita akan memerlukan dua tabel untuk hal ini, yakni tabel user, level, dan menu. Berikut sql query-nya.

CREATE TABLE IF NOT EXISTS `user` (
  `user_id` int(5) NOT NULL auto_increment,
  `user_nama` varchar(50) NOT NULL,
  `level_id` int(1) NOT NULL,
  `user_username` varchar(30) NOT NULL,
  `user_password` varchar(200) NOT NULL,
  PRIMARY KEY  (`user_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
INSERT INTO `user` (`user_id`, `user_nama`,`level_id`,`user_username`,`user_password`) VALUES
(1, 'Joko','1','jack',PASSWORD('jacktampan'),
(2, 'Ridwan','2','ridone',PASSWORD('alahmak'),
(3, 'Asep','1','darkfog',PASSWORD('darknessforever');
CREATE TABLE IF NOT EXISTS `level` (
  `level_id` int(1) NOT NULL auto_increment,
  `level_nama` varchar(30) NOT NULL,
  PRIMARY KEY  (`level_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
INSERT INTO `level` (`level_id`, `level_nama`) VALUES
(1, 'admin'),
(2, 'guru'),
(3, 'siswa');
CREATE TABLE IF NOT EXISTS `menu` (
  `menu_id` int(3) NOT NULL auto_increment,
  `menu_nama` varchar(30) NOT NULL,
  `menu_level` varchar(100) NOT NULL,
  PRIMARY KEY  (`menu_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;
INSERT INTO `menu` (`menu_id`, `menu_nama`,`menu_level`) VALUES
(1, 'Manajemen Menu','1'),
(2, 'Posting Berita','1+2'),
(3, 'Lihat Nilai','1+2+3');

Konsepnya adalah sebagai berikut :

  1. Tabel user menyimpan data user. Field penting yang terkait dengan sistem adalah level_id. Dengan level_id, kita dapat mengetahui level dari si user tersebut. Dalam contoh kita, kita sudah masukkan tiga orang user, masing masing level satu orang.
  2. Tabel level menyimpan referensi level dan namanya. Sebenarnya ini optional, tetapi akan sangat berguna untuk kerapihan struktur sistem. Dalam contoh kita, kita masukkan tiga level.
  3. Tabel menu menyimpan ‘sistem menu’ di dalam aplikasi yang kita buat. Disarankan dalam membuat controller grup admin (controller yang berisi fungsi pengolah halaman-halaman admin), supaya dipisahkan per menu. Misalkan untuk contoh ini, kita perlu tiga controller, yaitu controller ‘manajemen_menu’, ‘posting_berita’, dan ‘lihat_nilai’. Field menu_level disini mungkin agak aneh, tapi ini cukup untuk menyimpan referensi ‘siapa sajakah yang boleh membuka menu yang bersangkutan’. Misalkan disini,menu posting berita hanya boleh dibuka oleh level 1 dan 2 (dipisah dengan tanda ‘+’), tidak lain adalah level admin dan level guru. Begitu pula dengan yang lainnya.

Berikutnya, kita buat library untuk memudahkan pengelolaan user, seperti login dan restrict page.


if (!defined('BASEPATH')) exit('No direct script access allowed');
class Auth {
 function Auth()
 {
    $this->CI =& get_instance();
 }
 function process_login($login = NULL)
 {
    // cek apakah array login ada
    // array login dikirim dari form login berisi username dan password

    if(!isset($login))
        return FALSE;   
    // value dalam array hanya boleh ada 2

    // tidak lebih dan tidak kurang

    if(count($login) != 2)
        return FALSE;  
    // ambil data dari array

    $username = $login['username'];
    $password = $login['password'];
    // cari dalam database
    $this->CI->db->where('user_username', $username);
    $this->CI->db->where("user_password=PASSWORD('$password')");
    $query = $this->CI->db->get('user');
    if ($query->num_rows() == 1)
    {
        foreach ($query->result() as $row)
        {
            $user_id  = $row->user_id;
            $username = $row->user_username;
            $level   = $row->level_id;
            $nama   = $row->user_nama;
        }
        $newdata = array(
            'user_id' => $user_id,
            'username'  => $username,
            'level'     => $level,
            'nama'    => $nama
        );
        $this->CI->session->set_userdata($newdata);
        // set session tambahan

        $this->CI->session->set_userdata('logged_user', $username);
        return TRUE;
    }
    else 
    {
        // No existing user.
        return FALSE;
    }
  }   
 function restrict($logged_out = FALSE)
 {
    // fungsi ini untuk mengatur restriction sebuah halaman

    if ($logged_out && $this->logged_in())
    {
        // jika user sudah login tetapi ingin melihat halaman
        // yang tidak seharusnya dilihat, contoh halaman login
        redirect('menu'); // url helper, pastikan sudah ter-load
    }
    if ( ! $logged_out && ! $this->logged_in())
    {
        // jika user sudah logout (default :FALSE) dan dia
        // ingin masuk halaman admin

        redirect('home');
    }
 }
 function logged_in()
 {
    if ($this->CI->session->userdata('logged_user') == FALSE)
    {
        return FALSE;
    }
    else 
    {
        return TRUE;
    }
 }
 function logout()
 {
    $this->CI->session->sess_destroy();
    return TRUE;
 }
 function cek($idmenu)
 {
    // untuk mengecek apakah user mempunyai hak akses atau tidak
    $status_user=$this->CI->session->userdata('level');
    $this->db->select('menu_level');
    $this->db->from('menu');
    $this->db->where('menu_id',$id);
    $data = $this->db->get();
    $row=$data->row();
    $lev=$row->menu_level;
    $arr=explode('+',$lev);
    if(in_array($status_user,$arr)==FALSE)
    {
        redirect('home');
    }
 }
}

Untuk menggunakannya kita terapkan dalam controller login sebagai berikut.

<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); 
Class Login extends Controller
{
 function Login()
 {
    parent::Controller();
    $this->load->library('auth');
 }
 function login_form()
 {
    // restrict true agar user tidak bisa
    // melihat halaman ini ketika dia sudah login
    $this->auth->restrict(TRUE);
    $this->load->view('form_login');
 }
 function proses_login()
 {
    // ambil data dari form login, berisi username dan password
    $data_login = $_POST;
    $this->auth->process_login($data_login);
 }
 function logout()
 {
    $this->auth->restrict();
    $this->auth->logout();
    redirect('home');
 }
}

Selanjutnya, untuk setiap halaman yang akan dikontrol, kita cek dua kali, pertama cek apakah si user sudah login atau belum dan yang kedua cek apakah dia punya hak akses untuk melihat/membuka halaman tersebut. Pengecekan ini dilakukan di constructor dari controller (sehingga ber-efek ke semua fungsi dalam controller tersebut) menggunakan fungsi restrict() dan cek() yang sudah ada di paket library auth yang baru saja kita buat.


if (!defined('BASEPATH')) exit('No direct script access allowed');
Class Postingberita extends Controller
{
 function Postingberita()
 {
    parent::Controller();
    // cek apa dia sudah login
    $this->auth->restrict();
    // cek apa dia punya hak untuk mengakses menu posting berita (menu_id = 2)
    $this->auth->cek(2);
 }
}

OK kita selesai. Anda dapat membuat ‘panel manajemen menu’ jika anda memerlukannya. Lakukan update field menu_level dengan kombinasi level user dipisahkan dengan tanda ‘+’ (gunakan implode). Manajemen menu ini sangat perlu jika anda menginginkan menu Anda dinamis.

Feel free to comment. Good luck and happy coding!!

Related posts:

  1. Membuat Website dengan CodeIgniter #1
  2. Membuat Website dengan CodeIgniter #2
  3. Membuat Website dengan CodeIgniter #3
  4. Membuat Combobox Dinamis dengan CI dan Ajax
  5. Redirect dengan Delay Time di CodeIgniter

91 Comments

  • Okay, semua sudah saya coba, meskipun harus belajar lagi mengisi yang mas anggi ndak sampein, maklum newbe hehe,,
    kalo masih blm mudeng jangan sungkan2 menjawab ya,, nyante aja, hehe,, kebalik ya..
    Terima kasih

  • hohoho…siap. Good luck!

  • salam kenal… saya jadi tertarik mempelajari framework php dg CI setelah membaca artikel2 yg mas anggie buat. ijin copas ya… :D

  • Salam kenal juga….silakan….

  • mas anggy… tanya dong… :D

    $this->CI->db->where(“user_password=PASSWORD(‘$password’)”); <<< itu maksud "PASSWORD" apa mas… di file lib auth…

    Thanks yah…

  • PASSWORD itu adalah fungsi mySQL, sudah tersedia, untuk meng-enkripsi password…

  • ooo… semacem fungsi md5() gitu mas?

  • Iya, cuma bedanya kan klo md5 miliknya PHP

  • ini bentuk form loginnya kayak gmn ya, mas?
    saya boleh minta contoh file lengkapnya ga, mas anggi?
    ke email saya di bennozuke@gmail.com. kebetulan lg bikin aplikasi pake CI tapi bingung di loginnya, thanks

  • mas tanya lagi dong…

    $data_login = $_POST; <<< maksudnya apa mas…?

  • @ben : download aja web lengkap di http://www.mediafire.com/download.php?wmzei2frz3c

    @pak Doni : lewat email saja ya pak..

  • password admin yang MYCMS tuh apa ya koq ga masuk2
    mohon pencerahannya

    thx b4

  • generate yang baru saja…

  • mas, cara generate passnya gimana mas?

  • Fatal error: Call to undefined function js_insert_smiley() in C:\Program Files\xampp\htdocs\mycms\system\application\views\main\index.php on line 15

    gimana itu mas?

  • @agung: generate password di database langsung, tabel user, dengan fungsi mysql. ‘PASSWORD’.
    Untuk error yang smiley, pastikan ‘smiley helper udah diload mas…di masukkan ke autoload jg bisa…

  • bisa kasih contohnya ga untuk yang generate pass nya..soalnya udah di cobain eh ga tau knp gak mau…udah ngikutin chapta juga…masih aja gagal2 mulu

  • sekalian mas,minta file2 mas basis ci mas..buat belajar

  • Maaf untuk kesulitan generate password tersebut…ternyata setelah saya periksa lagi, password digenerate dengan fungsi PHP, bukan mysql. Tepatnya di library ‘encrypt.php’. Silakan menggunakan fungsi itu untuk generate password baru, lalu update user dengan password baru yang telah digenerate.

  • class CI_Encrypt {

    var $CI;
    var $encryption_key = ”;
    var $_hash_type = ‘sha1′;
    var $_mcrypt_exists = FALSE;
    var $_mcrypt_cipher;
    var $_mcrypt_mode;
    ini kan class dalam enryptnya mas..

    nah saya ubah
    class CI_Encrypt {

    var $CI;
    var $encryption_key = ‘md5′;//make md5
    var $_hash_type = ‘sha1′;
    var $_mcrypt_exists = FALSE;
    var $_mcrypt_cipher;
    var $_mcrypt_mode;
    koq tetep ae nya mas ga bisa-bisa juga….

    pusing de ga bisa masuk2 ke ruangan adminnya.
    helpp

  • salam kenal mas..saya masih pemula banget nie mas…mohon bimbingan’a y..coz PKL saya ngambil CI masih bener buta masalah CI..mas saya sudah download file’a knp y Q gag bisa nge’link’..pas pencet login Dsb malah keluar error ky gn : “Object not found!

    The requested URL was not found on this server. The link on the referring page seems to be wrong or outdated. Please inform the author of that page about the error.

    If you think this is a server error, please contact the webmaster.
    Error 404″

    gmn y??mohon bantuannya y..

  • oh y mas 1 lg,,hhe..link css’a kan ky gn y: “<link href="asset/stylesheet/screen.css” media=”screen” rel=”stylesheet” type=”text/css” /> ”

    klo ky gt gag bisa mas tapi pas Q ubah ky gn :
    baru bisa..itu knp y?

  • udah bisa mas link’a..ternyata d config’a blm di rubah..hhe…sekarang tgal CSS’a mas..sama Q belum paham untuk password generate’a..maklum newbie..hhe

  • Emm…maaf bru bisa balas…
    Untuk CSS, pakai URL LENGKAP aja, jadi pake fungsi di url_helper, base_url(). silakan baca lebih lanjut di user_guidenya

    Untuk Password, yang ini memang rada rumit. Saya sudah modifikasi salah satu library saya, bisa didownload di http://www.mediafire.com/download.php?yydygwinmum.

    Copy n replace di application/libraries/ untuk mengganti yang lama. Kemudian, generate password dengan fungsi mysql PASSWORD,

    UPDATE admin SET admin_password=PASSWORD('pass_anda') where admin_username='admin'
    
  • mas masih gag bisa nie password’a…Sql di atas maksud’a untuk merubah password pada tabel admin user_name admin dengan pass_anda y kan mas,,,tapi masih gag bisa..malah balik lg ke form login’a..gmn mas>????

  • udah direplace belum, ‘auth.php’ nya?

  • field artikel_static mana ya?…koq ga ada?

  • koq aq login ke admin page trus logout n abis itu aq tekan back button di browser malah masih bisa masuk ya mas n ga keluar?… berarti session destroy-nya ga jalan donk…

  • salam kenal mas. :D…. klo bikin link misalnya kaya gini…… http://blogku.com/2010/03/07/tutorial-codeigniter/

    masih bingung mas :p

  • @senz : tombol back itu memang begitu mas…coba saja Anda masuk menu…tak akan bisa. Karena sebenarnya session memang sudah hilang…

    @hendra : simpel saja, itu permainan database saja mas…klo dilihat dari yang Anda mau, querynya berdasar tahun, bulan,tanggal dan judul posting…

  • sudah mas tapi tetep aj balik lagi gag mw masuk login..pertama kan sy ubah user sama passwor’a dah gt file auth juga sudah si ganti tapi gag bisa jg..knp y mas..klo boleh sya minta file yg sudah jadi bisa gag mas..saya sebentar lg mau sidang PKL..hhe..tapi tetep masih bingung…huahh…mohon bantuan’a y mas..

  • Makasi bos,
    Akhirnya ketemu juga tutorial yang lengkab kaya gini……

  • sama-sama bos…thx dah mampir…

  • @rendy :

    rubah aja dulu sementara di phpmyadmin nya

    ruba passwordnya sesuka hatiww..:P

    terus… buka library/auth nya…

    ganti kode untuk select pass nya jadi kayak gini

    $this->CI->db->where(“user_password=PASSWORD(‘$password’)”);

    rubah menjadi

    $this->CI->db->where(‘user_password’, $password);

    pasti masuk ke halaman admin…

    tapi setelah login?

    cepet cepet ganti dengan pass baru nya lagi…

    kemudian undo tuh script auth nya..

    selesai…

  • bro untuk ini :
    // value dalam array hanya boleh ada 2

    // tidak lebih dan tidak kurang

    if(count($login) != 2)
    return FALSE;

    // ambil data dari array

    $username = $login['username'];
    $password = $login['password'];

    bisa lebih dari 2 ggk, misal $tipelogin = $login['tipelogin'];
    soalnya kebanyakan tutorial pasti 2.
    aku pingin pada saat login ada pilihin tipe loginnya misal kayak level gitu, level bukan dari usernya tapi pilihannya itu, and di cek ke tabel sesuai ggknya pilihan itu.
    udah mentok nih, udah coba oprek2 masih belum nemu juga, padahal di form login udah aku tambahin pilihan formnya

    thank’s , kalau ada refensi atau solusi tolong ke email ya :-)

  • Tentu bisa bro…
    Itu kan hanya contoh, tentu bisa dimodif lagi…
    sesuai kebutuhan dan selera ;)

  • mas, kok saya nyoba, css-nya g jalan yak…

  • CSS…biasanya saya pakai URL lengkap…memang tidak biasanya, tapi itu berhasil. Gunakan misal http://localhost/web/asset/css/style.css

  • dulu pas php lom diupgrade bisa..
    tapi biz diupgrade, malah ndak muncul.. T-T

  • Boleh diskusi lwt YM?

  • Silahkan…sudah tahu YM nya kan?

  • minta arahan algoritma + keterangan lain dari web warungmobil.com Buat belajar.. teirma kasih,,

  • @Taufiq : maksudnya gimana mas?

  • kenapa array nya harus 2 gak boleh lebih ga boleh kurang ??


  • boro:

    kenapa array nya harus 2 gak boleh lebih ga boleh kurang ??

    Soalnya saya hanya butuh 2 input mas, username sama password. Begitu mas…

  • Kenap nih errornya banyak amat yah… ?

    ===============================

    A PHP Error was encountered

    Severity: 8192

    Message: Function set_magic_quotes_runtime() is deprecated

    Filename: codeigniter/CodeIgniter.php

    Line Number: 60
    A PHP Error was encountered

    Severity: 8192

    Message: Assigning the return value of new by reference is deprecated

    Filename: libraries/Loader.php

    Line Number: 248
    A PHP Error was encountered

    Severity: 8192

    Message: Assigning the return value of new by reference is deprecated

    Filename: database/DB.php

    Line Number: 133
    A PHP Error was encountered

    Severity: Warning

    Message: Cannot modify header information – headers already sent by (output started at D:\xampp\htdocs\HIS\system\codeigniter\Common.php:123)

    Filename: libraries/Session.php

    Line Number: 403
    A PHP Error was encountered

    Severity: Warning

    Message: Cannot modify header information – headers already sent by (output started at D:\xampp\htdocs\HIS\system\codeigniter\Common.php:123)

    Filename: libraries/Session.php

    Line Number: 315

  • Upgrade Codeigniter Anda…

  • mas code terakhir baris $this->simplival->cek(2); kalau pake library di postingan ini jadinya $this->auth->cek(2); ya ?


  • nafri:

    mas code terakhir baris $this->simplival->cek(2); kalau pake library di postingan ini jadinya $this->auth->cek(2); ya ?

    Oh iya mas…terimakasih…sorry all…baru sadar saya klo salah…(sudah saya edit)

  • Waw, Matur nuwun nih mas… :D


Leave a comment