Minggu, 10 Juni 2012

Membuat Access Control List


Tulisan ini adalah lanjutan dari tulisan sebelumnya, kali ini kita akan bahas mengenai pembuatas Access Control List dengan frame work CodeIgniter, mengingat CI sendiri secara default tidak menyediakan modul ACL.
Pada tulisan sebelumnya, saya sudah jelaskan bagan program dan struktur databasenya. Itu yang akan kita pakai, kita terapkan di CodeIgniter. Sesuai bagan tidak ada hubungan langsung dari table users ke table rules yang menyimpan list class dan methods dari aplikasi yang kita punyai.
Jadi sesuai kesepakatan di atas:
  • seorang user harus tergabung dengan 1/+ groups
  • suatu group harus memiliki 1/+ roles
  • suatu role memiliki beberapa/banyak rules sesuai roles tersebut.
Di forum CodeIgniter saya menemukan orang baik yang membagi kode untuk administrasi ACL ini. Forum bisa dilihat lengkapnya di sini http://codeigniter.com/forums/viewthread/139747/ dan source program bisa didapatkan di sini http://svn.supergluetech.com/repositories/codeigniter/acl/.
Kode program dari Dean Rantala tersebut hanyalah berupa kumpulan fungsi yang bisa memudahkan pembuatan modul ACL ini, bukan aplikasi/atau modul siapa pakai, jadi masih perlu banyak modifikasi, karena memang belum lengkap. Beliau juga tidak menyediakan hubungan sampai ke table rules, hanya sampai table roles saja. Ini optional, boleh dimanfaatkan atau tidak. Berdasarkan bagan, arsitektur, dan aturan yang kita bahas pada tulisan sebelumnya, kita bisa membuat sendiri aplikasi administrasi untuk modul ACL ini, sesuai selera.
Saya sendiri tidak akan membahas cara pembuatan modulnya, karena dari bagan sudah jelas. Saya akan membahas trik-triknya pemanfaatan aplikasi berbasis CodeIgniter kita.
Membentuk session saat login
<?php
$session_data = array(
        ’user_classes’ => $login_user_class,  //array
        ’user_class_methods’ => $login_user_class_method,  //array
        ’user_id’ => $login_user_id,
        ’user_name’ => $login_user_name,
        ’user_description’ => $user_user_description,
        ’user_logged’ => TRUE
    );
$this->session->set_userdata($session_data);
?>
Perhatikan script di atas, itu session yang kita harus bikin saat user login.
  1. user_class : array list class dari user login, data class disimpan di table rules, ini optional, bisa memudahkan saat kita membentuk section navigasi aplikasi kita berdasarkan hak user login.
  2. user_class_methods : array list kombinasi class dan method dari user login, data method disimpan di table rules juga, mutlak harus ada, kombinasi ini yang akan kita bandingkan untuk menentukan user berhak atau tidak mengakses sebuah method dari class/controller kita
  3. Data selebihnya adalah data informasi user logged, tentu saja diperlukan.
  4. Contoh array yang dibentuk bisa dilihat di bawah.
Membandingkan kombinasi current class dan current method dengan array ‘user_class_methods’ yang di simpan di session.
Harus kombinasi yang kita bandingkan, agar tidak terjadi kesalahan, karena mungkin saja dari beberapa controller kita, ada nama method/function yang sama.
<?php
    $current_class = $this->uri->rsegment(1);
    $current_method = $this->uri->rsegment(2);
    $current_class_method = $current_class . "." . $current_method;
  
    $user_class_methods = $this->session->userdata(‘user_class_methods’);
  
    if(!in_array($current_class_method, $user_class_methods)){
        die(‘maaf, anda tidak punya akses ..’);
    }
?>
Pada script di atas saya mengkombinasikan keduanya dengan karakter . (titik), tentu saja harus sesuai dengan cara pengkombinasian saat session dibentuk. Pembandingan kombinasi current class dan current method menggunakan syntax in_array native PHP.
Manfaatkan hook CodeIgniter.
Ini dia trik yang sesungguhnya, hook CI. Jika di setiap method kita selalu menambahkan sebaris script di atas untuk control user tentu tidak bagus, jadul lagi. CI menyediakan fasilitas hook, yaitu suatu function atau method yang extend core CI, dipanggil saat aplikasi CI dijalankan, silahkan baca selengkapnya di sinihttp://codeigniter.com/user_guide/general/hooks.html.
Langkah memanfaatkan hook adalah sebagai berikut:
  1. Enable hook di application/config/config.php
  2. Daftarkan hook di application/config/hooks.php
  3. Buat hooknya di folder application/hooks, untuk script hooknya sendiri saya akan sertakan di tulisan ini,lihat di bawah.
Dengan hook CI, aplikasi kita akan terlihat rapi dan jauh lebih mudah dikelola, karena mekanisme Access Control terpusat. Controller dan method kita pun jadi bersih tanpa script untuk membandingkan session login dengan curent class-method.
Selamat mencoba, dan semoga bermanfaat.
Kode untuk di pasang di application/config/hooks.php
<?php
$hook['post_controller_constructor'] = array(
                                ‘class’    => ”,
                                ‘function’ => ‘isallowed’,
                                ‘filename’ => ‘isallowed.php’, // misalnya namanya demikian
                                ‘filepath’ => ‘hooks’,
                                ‘params’   => array()
                                );
?>
Kode application/hooks/isallowed.php
<?php
function isallowed() {
    $ci =& get_instance();
    $ci->load->model(‘acl’);
  
    $user_class_methods = $ci->session->userdata(‘user_class_methods’);
    $user_classes = $ci->session->userdata(‘user_classes’);
    $user_info = $ci->session->userdata(‘user_info’);
    $user_logged = $ci->session->userdata(‘user_logged’);
  
    $current_class = $ci->uri->rsegment(1);
    $current_method = $ci->uri->rsegment(2);
    $current_class_method = $current_class . "." . $current_method;
  
    if(!$user_logged and $current_class!=’login’){
        header("location: /login");
        exit;
    }
  
    // set controller yang user selalu HARUS BOLEH akses
    $all_allowed_classes = array(‘login’, ‘logout’, ‘home’, ‘forbidden’);
  
    if(!in_array($current_class, $all_allowed_classes)){
        if(!in_array($current_class_method, $user_class_methods) and !in_array($current_class, $all_allowed_classes)){
            header("location: /forbidden"); // arahkan ke halaman khusus forbidden
            exit;
        }
    }
}
?>
Contoh array yang dibentuk, agar lebih mudah membayangkan ..
Array 'user_class_methods'
(
    [0] => groups.index
    [1] => groups.edit
    [2] => groups.users
    [3] => groups.roles
    [4] => groups.add
    [5] => groups.update
    [6] => groups.delete
    [7] => groups.set_users
    [8] => groups.set_roles
    [9] => articles.list
 dst ...
)

Array 'user_classes'
(
    [0] => groups
    [9] => home
    [10] => roles
    [17] => rules
    [22] => users
    [31] => channels
    [37] => articles

 dst ...
)
 source

Tidak ada komentar:

Posting Komentar