Tuesday, December 30, 2008

Script pengatur waktu Session, Logout Otomatis

Banyak hal terjadi jika seseorang telah berhasil login sebagai user, dan tentunya login ini ada ketika user akan memanfaatkan layanan dari suatu website, bukan karena sebab yang lain, seperti tingkat sekuritas yang buruk. Selalu ada masa idle. Idle di sini bermakna user tidak melakukan apa-apa sama sekali di website tersebut, tidak berpindah halaman, tidak memasukkan input pada form manapun, dan tidak ada hal apapun yang menyebabkan sebuah halaman website terrefresh, dengan kata lain user tidak melakukan apa pun pada website yang sedang dia kunjungi. Sungguh user yang aneh. :D~~. Tapi hal seperti ini dapat terjadi jika user sedang asik mengunjungi website yang lain, dan lupa akan website yang dia kunjungi sebelumnya. Tentunya keadaan user pada website yang dikunjungi sebelumnya dianggap sebagai condition yang idle oleh website tersebut. Tidak ada hal apapun yang terjadi di website sebelumnya. Atau kondisi lain, dimana seorang user yang telah 10 menit meninggalkan pc-nya dalam keadaan lupa melogout accountnya. Sungguh terlalu. Di sinilah fungsi pengatur waktu session benar-benar dibutuhkan.

Ada dua cara untuk mengatur waktu session, yang pertama adalah merubah konfigurasi session timeout pada php.ini, cara yang terakhir yaitu dengan memanfaatkan fungsi time() dan variable session yang telah teregistrasi, dengan kata lain cara yang terakhir ini adalah merancang barisan code yang dapat mengatur waktu session. Penulis tidak akan menjelaskan cara yang pertama. Tapi yang akan penulis jelaskan adalah cara yang kedua. Penulis akan mengambil sebuah contoh kasus, ini untuk memudahkan penjelasan secara logika, dan penjelasan alur dari cara kerja script yang akan dibuat.
Kasusnya seperti ini, “Ketika user telah berhasil login, akan ada sebuah session yang digunakan sebagai patokan untuk membandingkan berapa lama user telah berada pada halaman website tersebut. Apabila waktu time() yang berjalan lebih besar dari nilai session dari variable yang dijadikan sebagai patokan nanti maka user tersebut akan secara otomatis terlogout”.

Secara struktur, algoritmanya akan seperti ini :

  1. Sediakan sebuah variable x, berisi waktu sekarang ditambah 30 detik.
  2. Jadikan variable x tersebut sebagai session, yang akan membypass valuenya pada setiap halaman, dengan kata lain, isi variable x tersebut dapat ditampilkan di halaman mana pun.
  3. Bandingkan waktu sekarang dengan nilai dari variable x tersebut.
  4. Jika waktu sekarang lebih kecil dari nilai variable x tersebut, maka si user masih dalam keadaan login.
  5. Jika waktu sekarang lebih besar dari nilai variable x tersebut, maka keadaan si user adalah logout.
  6. Jika user melakukan refresh halaman, berpindah halaman, mengisi form, sebelum masa sessionnya habis maka waktu login di tambah 10 menit berikutnya.

Ya, untuk algoritma di atas penulis bagi menjadi 2 function, yakni function login_validate() dan login_check(). Langsung saja persiapkan script yang dibutuhkan :

File index.php :


require_once "functions.php";
if (( $_POST['username'] == 'admin' ) && ( $_POST['password'] == 'admin'))
{
$_SESSION['user'] = $_POST['username'];
login_validate();
header("location: admin.php");
}

else if ( empty($_POST['username']) && empty($_POST['password']) )
{
header("location: login.php");
}

?>

Selanjutnya file intinya yaitu,
functions.php :


session_start();

function login_validate() {
$timeout = 30;
$_SESSION["expires_by"] = time() + $timeout;
}

function login_check() {
$exp_time = $_SESSION["expires_by"];
if (time() < $exp_time) {
login_validate();
return true;
} else {
unset($_SESSION["expires_by"]);
return false;
}
}
?>

Kemudian admin.php, barisan code dalam admin.php ini penulis ibaratkan seperti kondisi dari admin yang telah berhasil login. Jika lebih dari 30 detik maka user secara otomatis akan di logout. Nilai 30 detik ini diambil dari variable $timeout yang ada di functions.php.

File Admin.php :


require_once "functions.php";

if (ISSET($_SESSION['user']))
{
if (!login_check()) {
header("Location: logout.php");
exit(0);
}
else {
echo "Jika tidak ada kegiatan sama sekali, anda akan logout secara otomatis ... ";
}
}

else
{
echo "Anda tidak berhak untuk ngapa-ngapain ... !! :D";
}

?>

Selanjutnya halaman login usernya, login.php :








username
password






Terlihat jelas pada baris ke 4 di atas, halaman login page memiliki action, menuju index.php, yang kemudian menghasilkan 2 variable POST, yaitu $_POST[‘username’], dan $_POST[‘password’]. Kedua variable inilah yang kemudian dicek pada halaman index.php.

Dan yang terakhir adalah logout.php :


require_once "functions.php";

unset($_SESSION['user']);
session_destroy();
header("location: login.php");

?>


Cara kerja source code di atas cukup sederhana, lihat barisan code index.php,

......
if (( $_POST['username'] == 'admin' ) && ( $_POST['password'] == 'admin'))
{
$_SESSION['user'] = $_POST['username'];
login_validate();
header("location: admin.php");
}

else if ( empty($_POST['username']) && empty($_POST['password']) )
{
header("location: login.php");
}
....

Penjelasannya adalah sebagai berikut, Jika user memasukkan username dan password yang cocok ( dalam kasus ini username dan passwordnya adalah admin ) maka user akan diberikan sebuah variable session, yakni $_SESSION['user'], dan akan ditambahkan sebuah variable baru yang nantinya variable ini berfungsi sebagai timer, yakni

$timeout = 30;

Variable tersebut berada dalam fungsi login_validate() pada script functions.php. Sedangkan masih dalam fungsi login_validate, lompat ke barisan code dibawahnya yaitu :

$_SESSION["expires_by"] = time() + $timeout;

Disinilah letak timer yang sebenarnya, kehebatan dari session adalah dapat melakukan passing value walaupun halamannya berbeda. Jelasnya $_SESSION["expires_by"] mengambil nilainya dari waktu ketika user pertama kali login yaitu time() di tambah dengan 30 detik kedepannya, yakni isi dari variable $timeout.

Nah, dari situ, lihat ke bagian fungsi yang ada di bawahnya, pada functions.php :

...
function login_check() {
$exp_time = $_SESSION["expires_by"];
if (time() < $exp_time) {
login_validate();
return true;
} else {
unset($_SESSION["expires_by"]);
return false;
}
}
....

Ya, lihat baris :
$exp_time = $_SESSION["expires_by"];

Varibale $exp_time itu memiliki nilai dari $_SESSION["expires_by"],
Untuk kejelesannya penulis berikan contoh seperti ini, jika user login pada waktu jam 5, maka $_SESSION["expires_by"] berisi jam ke 5, menit ke 0, dan detik ke 30. Dan secara alami pun diketahui bahwa yang namanya waktu pasti akan terus bertambah tentunya. Tapi karena berada dalam fungsi, variable $_SESSION["expires_by"] ini tidak akan bertambah, walaupun time() terus berlanjutnya.

Lompat ke baris selanjutnya :
if (time() < $exp_time) {
login_validate();
return true;

Dalam baris tersebut sederhananya adalah, jika waktu yang sekarang berjalan lebih kecil nilainya dari nilai yang ada pada $_SESSION["expires_by"], maka tambahkan 30 detik lagi, dan jika waktu pada time() sama dengan nilai $_SESSION["expires_by"] maka user akan otomatis logout

Selanjutnya ...
...
else {
unset($_SESSION["expires_by"]);
return false;
}
...

Jika waktu yang sekarang berjalan itu lebih besar dari nilai yang ada pada $_SESSION["expires_by"], maka lakukan logout.

Script tersebut dapat di download di sini
http://networkandgame.890m.com/ilmuwebsite/article/session-time-by-alk.zip
Cukup jelas ya. Jika ada yang di tanyakan, silahkan layangkan pertanyaan ke email penulis.

Redirect Halaman Kompleks

Lagi-lagi penulis coba untuk membayar hutang. :D. Hutang mengenai tutorial yang membahas redirect halaman secara kompleks. Sebelum menuju inti pembahasan, penulis akan beri penjelasan apa dan bagaimana contoh kasus dari redirect halaman secara kompleks ini.
Mungkin ada sebagian orang yang pernah mencoba searching di google mengenai artikel yang dia cari, namun ketika mendapatkan artikel tersebut, web tersebut hanya membolehkan user yang sudah teregistrasi saja yang dapat mengakses artikel tersebut. Maka, langkah selanjutnya yang dilakukan oleh user tersebut adalah meregistrasikan dirinya untuk menjadi member pada website tersebut, pada form yang letak halamannya berbeda dengan artikel yang dicari. Namun setelah proses registrasi selesai, dan proses login berhasil, user secara otomatis di redirect ke halaman yang dia tuju sebelumnya. Ini adalah contoh kecil dari redirect kompleks. Contoh lainnya, ketika user yang akan mencoba untuk mendownload sebuah file pada halaman tertentu di suatu website, user tersebut diharuskan untuk login terlebih dahulu, tapi setelah login user langsung diredirect secara otomatis menuju halaman download. :D. Pada tutorial kali ini, penulis akan coba jawab itu berbagai persoalan tersebut. Mari .. mari ... :D

Ya, persiapkan terlebih dulu databasenya :

create database simple_cms ;
use simple_cms ;
create table user( id int(5) PRIMARY KEY auto_increment, username varchar(20), password varchar(50));
create table article (id int(5) PRIMARY KEY auto_increment, penulis varchar(20), judul varchar(200), isi text);

insert into user values ('','admin',md5('admin'));
insert into article values('','Loka Dwiartara','Kegantengan Abadi','Kegantengan abadi terpancar dari kekerenan sejati. Aura kegantengan selalu terpancar dari kerennya seseorang. :D. Kadang banyak yang berpikir keindahan secara fisik itu melebihi dari segalanya. Kita tahu bahwa b_scorpio itu tidak ganteng, tapi setidaknya tolong hargai dia :D'), ( '','Loka Dwiartara','PHP is powerfull easy language ... ', 'Kekerenan php dalam menangani pengembangan sistem informasi berbasis website patut di acungi 4 jempol kaki dan tangan, kehebatannya melebihi b_scorpio yang tidak pandai menggaet i#a, wanita yang dia suka. ;D~~~, peace ... damai ... ') ;

Selanjutnya, config.php :

$host = "localhost";
$username = "root";
$password = "";
$database = "simple_cms" ;

$connect = mysql_connect($host, $username, $password);
mysql_select_db( $database , $connect) or die ("MySQL is error!!");
?>

Kemudian, halaman login.php :






username
password






Selanjutnya, file cek.php, disinilah redirect kompleks halaman berada :


session_start();
require_once "config.php";

if (ISSET($_POST['username']) && ISSET($_POST['password']) )
{
$username = $_POST['username'];
$password = md5($_POST['password']);
$session_halaman = $_SESSION['halaman'];

$cekuser = "select username, password from user where username = '$username' and password = '$password'";
$query_cekuser = mysql_query($cekuser);
$exist = mysql_num_rows($query_cekuser);

if ($exist >= 1)
{
$_SESSION['user'] = session_id();
header("location: index.php?view=page&id=$session_halaman");
}

else
{
header("location: login.php");
}

}

?>

Dan halaman index.php, untuk menampilkan artikelnya :


session_start();
require_once "config.php";
if (!ISSET($_REQUEST['id']) )
{
$list_article = "select * from article";
$query_list_article = mysql_query($list_article);
echo "

Article Today

";

if (ISSET($_SESSION['user']))
{
echo "

Welcome back User. Do you want logout ? :D~~

";

}


while ($showlist = mysql_fetch_array($query_list_article))
{
$id = $showlist['id'];
$penulis = $showlist['penulis'];
$judul = $showlist['judul'];
$isi = $showlist['isi'];
$panjangartikel = strlen($isi);
$isi_dipotong = substr($isi, 0, 60);
$isi_fix = substr($isi, 0, strrpos($isi_dipotong, " "));
$isi_fix .= "...";

echo "$judul

Oleh : $penulis

$isi_fix selengkapnya



";


}
}

else if (ISSET($_REQUEST['view']) && ISSET($_REQUEST['id']) )
{

$id = $_REQUEST['id'] ;
if (!ISSET($_SESSION['user']))
{
$_SESSION['halaman'] = $id ;
echo "Login dulu dong di sini";
}

else
{
$list_article = "select * from article where id = '$id' ";
$query_list_article = mysql_query($list_article);

while ($showlist = mysql_fetch_array($query_list_article))
{
$id = $showlist['id'];
$penulis = $showlist['penulis'];
$judul = $showlist['judul'];
$isi = $showlist['isi'];

echo "

Article Today

";

echo "$judul

Oleh : $penulis

$isi



";


}

echo "Kembali...";
}

}

?>


Terakhir adalah, file logout.php :


session_start();
unset($_SESSION['user']);
session_destroy();
header("location: index.php");
?>

Hmmm.. panjang juga scriptnya. :D~ Penulis coba jelaskan beberapa baris yang penting saja. Lihat ke halaman index.php, di situ terdapat baris seperti ini :

....
else if (ISSET($_REQUEST['view']) && ISSET($_REQUEST['id']) )
{

$id = $_REQUEST['id'] ;
if (!ISSET($_SESSION['user']))
{
$_SESSION['halaman'] = $id ;
echo "Login dulu dong di sini";
}


...

else if (ISSET($_REQUEST['view']) && ISSET($_REQUEST['id']) )
Ini berarti, jika user mengklik salah satu artikel di halaman index,

if (!ISSET($_SESSION['user']))
dan jika user belum login,

$_SESSION['halaman'] = $id ;
maka, rekam halaman yang akan dibuka, simpan halaman tersebut ke dalam variable session.

echo "Login dulu dong di sini";
Persilahkan user untuk login dulu.

Nah selanjutnya, jika user telah login maka artikel langsung di perlihatkan seluruhnya, seperti pada baris ini

....
else
{
$list_article = "select * from article where id = '$id' ";
$query_list_article = mysql_query($list_article);

while ($showlist = mysql_fetch_array($query_list_article))
{
$id = $showlist['id'];
$penulis = $showlist['penulis'];
$judul = $showlist['judul'];
$isi = $showlist['isi'];

echo "

Article Today

";

echo "$judul

Oleh : $penulis

$isi



";


....

Kemudian untuk script cek.php

if (ISSET($_POST['username']) && ISSET($_POST['password']) )
Jika user telah mengisi password dan username,

....

$cekuser = "select username, password from user where username = '$username' and password = '$password'";
maka buat sebuah query yang akan menyeleksi apakah username dan passwordnya ada.

...

$query_cekuser = mysql_query($cekuser);
Jalankan querynya ...

$exist = mysql_num_rows($query_cekuser);
Apakah username dan password yang dimasukkan tersebut ada dalam database?

if ($exist >= 1)
{
Jika ada,

$_SESSION['user'] = session_id();
maka buat session baru untuk user

header("location: index.php?view=page&id=$session_halaman");
Redirectkan si user ke halaman yang dia tuju sebelumnya ... Ya, disinilah letak dari redirect kompleksnya. :D. Cukup manfaatkan saja session yang ada untuk meredirect user ke halaman yang dituju.

}

else
{
header("location: login.php");
jika username dan password salah, persilahkan user untuk login ulang.

}

}
Untuk screenshoot demonya seperti ini :


Ini adalah halaman pertama kali


Ketika salah satu link akan diklik, maka user diperintahkan untuk login terlebih dahulu


Setelah login berhasil maka user secara otomatis langsung di redirect ke halaman tujuan yang awal.


Yup, penulis kira sudah cukup jelas untuk redirect kompleks. Jika ada yang ditanyakan silahkan kirim email ke alkemail@gmail.com. Selamat mencoba.

Script tersebut dapat di download di sini
http://networkandgame.890m.com/ilmuwebsite/article/redir-complex-by-alk.zip

Greetz : b_scorpio, abuzahra, peterpanz, kandar, phii_, syahrilrohman, ivan, dr.emi, safril, najwa. Special for jojo. :). Hi, Jo! Have a nice day.

Monday, December 22, 2008

Sistem Quota ala Speedy dengan Squish

Hufff, dah lama kita nggak ketemu. :D~~ Kira-kira beberapa bulan yang lalu, saya mencoba mencicipi layanan speedy personal, dan nggak kerasa, baru sekitar 10 hari, bandwithnya sudah overquota, lebih 7 mB kalo nggak salah. Padahal penulis sendiri waktu itu hanya diberikan jatah 1 GB perbulannya. Wekzz !! Maklum penulis termasuk orang yang rakus dalam pemakaian bandwith. :D. Download download ... !!! Terpaksa merogok kocek saku sang mahasiswa yang notebenenya selalu bokek :D~~~.


Tapi berhubung sakunya bolong mau bagaimana lagi, terpaksa pemakaian internet di rumah di cabut. :(~

Kali ini penulis mencoba untuk menjelaskan sebuah system quota ala speedy, dengan pembatasan berdasarkan waktu dan kapasitas pemakaian tentunya.

Kita ambil contoh : user A di berikan batas waktu pemakaian 5 jam, dan 20 MB perharinya. Walaupun sebelum 5 jam kapasitasnya sudah full maka sang user terpaksa menunggu hari berikutnya untuk bisa kembali bermain. Istilah kerennya yakni Squished.

System quota ini menggunakan sebuah paket aplikasi tambahan, Squish. Yang penulis gunakan adalah squish versi 0.0.18.

Di tutorial ini penulis menggunakan distro fedora core 4, yang didalamnya telah terinstall paket squid. Berikut adalah peralatan yang kita butuhkan nantinya :

gd-2.0.33-2.i386.rpm
perl-GD-2.35-1.fc4.i386.rpm
squish-0.0.18.tar.gz

Download dulu paket-paket di atas :
# wget http://h1.ripway.com/ilmuwebsite2/gd-2.0.33-2.i386.rpm
# wget http://h1.ripway.com/ilmuwebsite2/perl-GD-2.35-1.fc4.i386.rpm
# wget http://h1.ripway.com/ilmuwebsite2/squish-0.0.18.tar.gz

Kemudian Install paket gd-2.0.33-2.i386.rpm, dan perl-GD-2.35-1.fc4.i386.rpm
# rpm –ivh gd-2.0.33-2.i386.rpm
# rpm –ivh perl-GD-2.35-1.fc4.i386.rpm

Setelah itu ekstrak file squish-0.0.18.tar.gz :
# tar –xzvf squish-0.0.18.tar.gz

Terdapat sebuah direktori baru disana, squish-0.0.18, kemudian masuk kedalamnya, kemudian install :
# cd squish-0.0.18
# make install

Pindah ke direktori di mana squish berada :
# cd /usr/local/squish/

Kemudian jalankan option run pada file squish.pl, ini dilakukan untuk membuat sebuah tampilan awal dari pemakaian bandwith :

# ./squish.pl --install

Dengan fasilitas crontab tambahkan sebuah perintah baru untuk daemon crond :

# crontab -e
5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/local/squish/squish.cron.sh

Kemudian tekan ESC :x!

Jalankan perintah baru tersebut untuk pertama kalinya :

# /usr/local/squish/squish.cron.sh

Kemudian kita tambahkan authentikasi ncsa_auth pada file konfigurasi squid.conf yang terletak di /etc/squid/squid.conf :

# nano /etc/squid/squid.conf
# baris ini ditambahkan di area authentikasi

auth_param basic program /usr/lib/squid/ncsa_auth /etc/squid/passwd
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours

# yang ini ditambahkan pada area acl
acl ncsa proxy_auth REQUIRED

# kemudian simpan
Setelah itu edit di bagian bawah baris kalimat ini

### added by squish (begin)

Menjadi seperti ini :

# acl's for squish - autodetected, sometimes
acl SQUISHLOC dst ns.multimedia.com
acl SQUISHED1 proxy_auth -i "/etc/squid/squished"

#acl SQUISHED2 ident "/etc/squid/squished"
acl SQUISHED3 src "/etc/squid/squished"
acl password proxy_auth REQUIRED

# Error info that says you're squished
deny_info http://ns.multimedia.com/squish/?squished& SQUISHED1

# deny_info http://ns.multimedia.com/squish/?squished& SQUISHED2
deny_info http://nd.multimedia.com/squish/?squished& SQUISHED3

# HTTP access controls for squish

http_access allow SQUISHLOC
http_access allow password !SQUISHED1
http_access deny SQUISHED1

# http_access deny SQUISHED2

http_access deny SQUISHED3

### added by squish (end )

http_access allow ncsa


Kemudian, edit file konfigurasi httpd :

# nano /etc/httpd/conf/httpd.conf
# tambahkan baris berikut di paling bawah dari file konfigurasi tersebut :

include /usr/local/squish/apache-squish.conf

Kemudian edit file apache-squish.conf :
# nano /usr/local/squish/apache-squish.conf

Edit file tersebut menjadi seperti ini :
Alias /squish "/usr/local/squish/"


Options +ExecCGI
AddHandler cgi-script .cgi
DirectoryIndex squish.cgi
AllowOverride None
Order allow,deny
Allow from all

Di bagian terakhir, anda cukup membuat user yang diperbolehkan untuk mengakses internet, dengan membuat sebuah file yang berisi user yang diperbolehkan login :

# htpasswd /etc/squid/passwd mamang

Berikan permission r untuk user lain agar file /etc/squid/passwd dapat dibaca oleh apache.

# chmod o+r /etc/squid/passwd

Kemudian restart service squid dan httpd :

# service squid restart
# service httpd restart

Untuk melakukan pembatasan pemakaian pada user, silahkan edit file konfigurasi squish.conf

# nano /etc/squid/squish.conf

squish.conf:
# This file contains data formatted as follows:
#
# Blank lines and hashed stuff is for comments
# user amount/period
# bandwidth: 999[kmG]b / period: day, week, month
# time: 999[smh] / period: day, week, month
#
# Whitelist entries - they can have as much as they like

192\.168\.99\.44 25h/day
192\.168\.97\.43 25h/day

mamang 12h/day 120Mb/day

# Poor guy:
root 1h/day 1Mb/day 2Mb/week

# Catchall -- people and IP's not matched by the above rules
.* 4h/day 20Mb/day 20h/week 100Mb/week

Tampilan ketika user habis masa pemakaiannya.