Hari ni aku teringat salah 1 janji aku pada seseorang yg masih belum ditunaikan, iaitu nak tunjukkan cara untuk buat user login atau user authentication dalam PHP7.2. Sebelum ni dia dah buat dalam PHP5 guna function mysql_connect, tapi bila masuk PHP7 nanti, function tu dah takde. Alang-alang nak tunaikan janji, aku kongsikan terus untuk semua agar ramai yg dapat manfaat. Tambahan pulak PHP5.6 akan tamat tempoh security support pada 31 Disember 2018, jadi adalah lebih baik untuk get ready dengan function yg valid dalam PHP7.2. Kenapa bukan PHP7? Sebab PHP7 akan tamat tempoh security support dia pada 3 Disember 2018, lebih awal daripada PHP5.6. Aku pon tak pasti kenapa situasi tu boleh berlaku, kena tanya Rasmus Lerdorf sendiri huhu. Walaubagaimanapon cara yg bakal aku tunjukkan ni adalah masih valid dalam PHP5.6. So tak jadi masalah untuk terus migrate coding sekarang walaupon masih menggunakan PHP5.6.
Objektif entry kali ni adalah aku nak tunjukkan cara asas yg aku buat tentang macam mana PHP detect seseorang tu dah login ke system ataupon belum.
Benda yg aku nak highlight adalah;
- Cara connect ke MySQL database (DB) menggunakan PHP7.2.
Aku pernah jumpa ada orang buat DB connection dengan cara hard-code di setiap PHP script. File index.php ada mysql_connect, file user.php pon ada benda tu, boleh kata hampir semua file .php tu dia letak DB connection string. - Buat input (HTML form) dengan method POST.
Aku pernah jumpa orang guna GET method. Dah la guna GET, tak pakai HTTPS pulak tu. - Proses input daripada form menggunakan PHP (termasuk MD5 hashing untuk sensitive data macam password).
Aku selalu jumpa orang store password in plain text dalam DB. - Cara guna PHP session untuk detect user login session.
Aku kadang-kadang jumpa orang dummy kan je guna folder. Page login tu hanya sekadar hiasan je dan bukannya untuk tujuan nak proseskan input data. Contoh; /admin untuk admin padahal user biasa pon boleh masuk.
Tonton dulu video ni untuk tengok macam mana user authentication in action dan test case yg aku buat, then bolehlah download source code kat bawah ni kalau nak test / belajar.
Sebelum ke bahagian teknikal / coding, kita cuba fahamkan dulu istilah user authentication supaya senang nak fahamkan benda2 lain yg berkaitan dengannya macam system logs. User authentication adalah proses untuk membolehkan seseorang user akses ke sesebuah system seterusnya membenarkan dia melakukan aktiviti yg dibenarkan dalam system tu. Contohnya tambah rekod jualan, edit, delete, dan sebagainya. Mengikut pemahaman aku, user authentication adalah wajib dalam sesebuah web-based system untuk nak pastikan hanya user berkenaan sahaja boleh melakukan aktiviti tertentu melalui user level yg disetkan kepadanya. Contohnya, bila seseorang user tu adalah system administrator, dia boleh manage semua rekod dalam system tu, tapi bila seseorang tu hanyalah staff, dia boleh manage rekod jualan sahaja.
Sekarang kita masuk ke bahagian teknikal untuk buat implementasi dalam PHP7.2 dan MariaDB10.1. Guna MySQL pon takde masalah selagi mana phpMyAdmin boleh communicate ngan server tu. Aku tunjukkan sekali dalam script tu macam mana nak hash password guna MD5 supaya kita faham kenapa tiada sesiapa pon tahu apa password sebenar sesebuah user account tu melainkan user tu sendiri. Aku pecahkan pada 2 bahagian utama;
Bahagian 1 : DB structure script;
Cuba belajar gunakan user selain root untuk buat web macam yg pernah aku cerita kat https://blogs.k-ict.org/afi/tips-untuk-secure-mysql-db-user/. Import structure ni ke DB korang.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
-- phpMyAdmin SQL Dump -- version 4.4.15.10 -- https://www.phpmyadmin.net -- -- Host: localhost -- Generation Time: Oct 07, 2018 at 09:39 PM -- Server version: 10.1.36-MariaDB -- PHP Version: 7.2.10 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; -- -- Database: `training_system_user_v01` -- CREATE DATABASE IF NOT EXISTS `training_system_user_v01` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci; USE `training_system_user_v01`; -- -------------------------------------------------------- -- -- Table structure for table `users` -- DROP TABLE IF EXISTS `users`; CREATE TABLE IF NOT EXISTS `users` ( `id` int(8) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `lastupdated_at` timestamp NULL DEFAULT NULL, `email` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `level` varchar(255) NOT NULL DEFAULT 'Staff', `password` varchar(255) NOT NULL, `enabled_status` enum('0','1') NOT NULL DEFAULT '0' ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; -- -- Dumping data for table `users` -- INSERT INTO `users` (`id`, `created_at`, `lastupdated_at`, `email`, `name`, `level`, `password`, `enabled_status`) VALUES (1, '2018-10-07 20:56:18', NULL, 'admin@test.com', 'Tuan admin', 'Administrator', 'acca5d75986268636decd87dca18c23f', '1'), (2, '2018-10-07 20:56:30', NULL, 'staff@test.com', 'Puan staff', 'Staff', 'f3808344ae99bfb8e26a9e5a08a5e63a', '1'); -- -- Indexes for dumped tables -- -- -- Indexes for table `users` -- ALTER TABLE `users` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `User email` (`email`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `users` -- ALTER TABLE `users` MODIFY `id` int(8) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3; |
Bahagian 2 : Coding / PHP script;
Sediakan 6 files macam kat bawah ni. Bagi yg tahu guna Git, boleh pull dari repo GitHub aku atau download ZIP file terus. Bagi yg belum biasa ngan GitHub, inshaAllah nanti aku buat tutorial lain pulak. Copy masuk semua file ni ke web server korang.
1 2 3 4 5 6 7 |
<?php # Step 1 : Senaraikan variables untuk connection ke DB. $mysql_hostname = 'localhost'; # MySQL server hostname. $mysql_username = 'user01'; # MySQL server username. $mysql_password = 'abc123'; # MySQL server user password. $mysql_db_name = 'training_system_user_v01'; # MySQL server DB name. ?> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php # Step 1 : Gunakan function ni untuk track web session bagi seseorang visitor. session_start(); # Step 2 : Declare file yg mengandungi PHP variables untuk configuration files. $config_file = 'config.php'; # Step 3 : Cek sama ada file config tu wujud atau tak. if(file_exists($config_file)) # Jika file berkenaan wujud, buat benda dalam kurungan { } ni. { include $config_file; $mysqli_connect = mysqli_connect($mysql_hostname, $mysql_username, $mysql_password); # Connect ke MySQL server menggunakan PHP variables dalam configuration files. if($mysqli_connect) # Kalau boleh connect, teruskan buat benda kat bawah ni. $mysqli_select_db = mysqli_select_db($mysqli_connect, $mysql_db_name); # Select DB yg nak digunakan. else die('Unable to use DB '.$mysql_db_name); # Kalau tak boleh connect, display error message kat browser. } else # Kalau tak wujud, buat benda kat bawah ni. die('File '.$config_file.' does not existed.'); # Display error message kat browser. ?> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?php # Step 1 : Include je file yg dah ada PHP session initialization dan DB connection string tadi, jadi tak perlu ulang banyak kali connect ke DB. include 'database.php'; # Step 2 : Cek sama ada user dah login ke belum. if(isset($_SESSION['users_id']) && isset($_SESSION['users_email']) && isset($_SESSION['users_name']) && isset($_SESSION['users_level'])) # Kalau server detect sessions kat senarai ni sudah diset maksudnya user dah login ke system. { ?> Anda sudah login ke system ini. <p> <input type="button" value="Teruskan ke Dashboard" onclick="location='03_dashboard.php';" /> </p> <?php } else # Kalau belum login, paparkan form untuk user login. { # Step 3 : Display user login form kalau user tu belum login. ?> <form method="post" action="02_process.php"> <!-- Ini adalah form untuk nak capture user input. Input akan dihantar untuk proses di file 02_process.php --> <table> <tr align="left" valign="top"> <td width="30%">Email address</td> <td><input name="email" type="text" value="" /></td> </tr> <tr> <td>Password</td> <td><input name="katalaluan" type="password" value="" /></td> </tr> <tr align="center"> <td colspan="2"> <input name="submitBtn" type="submit" value="Login" /> <input name="resetBtn" type="reset" value="Kosongkan" /> </td> </tr> </table> </form> <?php } ?> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
<?php # Step 1 : Include je file yg dah ada PHP session initialization dan DB connection string tadi, jadi tak perlu ulang banyak kali connect ke DB. include 'database.php'; # Step 2 : Cek sama ada user dah login ke belum. if(isset($_SESSION['users_id']) && isset($_SESSION['users_email']) && isset($_SESSION['users_name']) && isset($_SESSION['users_level'])) # Kalau server detect sessions kat senarai ni sudah diset maksudnya user dah login ke system. { ?> Anda sudah login ke system ini. <p> <input type="button" value="Teruskan ke Dashboard" onclick="location='03_dashboard.php';" /> </p> <?php } else # Kalau belum login, cuba proses input yg di POST dari 01_input.php { # Step 3 : Proses apa yg sepatutnya berlaku bila user masukkan input. # By default, initialize PHP variables untuk elakkan PHP warning dipaparkan jika tiada data di POST dari file 01_input.php, dan jugak untuk variable lain macam error message yg akan terlibat dalam file ni. $users_email = null; $users_password = null; $query_error = null; if(isset($_POST['email'])) # Input ni adalah daripada <input name="email" type="text" value="" /> tadi. Perhatikan bahawa attribute 'name' yg diambil kira sebagai PHP variable yg di POST. $users_email = addslashes($_POST['email']); # addslashes tu adalah untuk tambah slash / sekiranya ada special character yg digunakan macam simbol 'quotation marks', iaitu " if(isset($_POST['katalaluan'])) # Input ni adalah daripada <input name="katalaluan" type="password" value="" /> tadi. $users_password = $_POST['katalaluan']; # Sini tak perlu guna function addslashes sebab nanti kita akan hash guna function MD5. $users_password_hashed = md5($users_password); # MD5 hash adalah password yg telah ditukar daripada teks biasa yg boleh kita baca kepada suatu format lain yg manusia tak boleh faham. $query_statement01 = "select * from `users` where `email` = '$users_email' and `password` = '$users_password_hashed'"; # Buat statement SELECT untuk cari data dengan email dan password (hashed dengan MD5) yg dimasukkan. $query01 = mysqli_query($mysqli_connect, $query_statement01); # Execute SQL query. $query_error = mysqli_error($mysqli_connect); # Cek kalau2 ada error kat query. if(!$query_error) # Kalau takde error, buat benda kat bawah ni. { $query02 = mysqli_num_rows($query01); # Kira berapa banyak data / rows yg dijumpai daripada query tu. if($query02) # Kalau data dijumpai, maksudnya email & password yg dimasukkan tu adalah betul. { $query03 = mysqli_fetch_assoc($query01); # Ini adalah data daripada row kat table users. $users_id = $query03['id']; $users_email = $query03['email']; $users_name = $query03['name']; $users_level = $query03['level']; # Setkan user + browser session, iaitu untuk kita jadikan user ni logged-in / authenticated dalam system tu. $_SESSION['users_id'] = $users_id; $_SESSION['users_email'] = $users_email; $_SESSION['users_name'] = $users_name; $_SESSION['users_level'] = $users_level; echo 'Anda telah berjaya login ke system.'; ?> <p> <input type="button" value="Teruskan ke Dashboard" onclick="location='03_dashboard.php';" /> </p> <?php } else # Kalau takde data, buat benda bawah ni. { ?> Maaf, kombinasi email dan katalaluan adalah salah, atau tiada data dimasukkan. <p> <input type="button" value="Balik ke login form" onclick="location='01_input.php';" /> </p> <?php } } else # Kalau ada error, buat benda kat bawah ni. die($query_error); # Display error message. } ?> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php # Step 1 : Include je file yg dah ada PHP session initialization dan DB connection string tadi, jadi tak perlu ulang banyak kali connect ke DB. include 'database.php'; # Step 2 : Cek sama ada user dah login ke belum. if(isset($_SESSION['users_id']) && isset($_SESSION['users_email']) && isset($_SESSION['users_name']) && isset($_SESSION['users_level'])) { ?> <h3>Selamat datang, <?php echo $_SESSION['users_name']; ?>!</h3> <p> <input type="button" value="Logout" onclick="location='04_logout.php';" /> </p> <?php } else { ?> Maaf, anda tidak dibenarkan akses ke bahagian ini. <p> <input type="button" value="Balik ke login form" onclick="location='01_input.php';" /> </p> <?php } ?> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php # Step 1 : Include je file yg dah ada PHP session initialization dan DB connection string tadi, jadi tak perlu ulang banyak kali connect ke DB. include 'database.php'; # Step 2 : Cek sama ada user dah login ke belum. if(isset($_SESSION['users_id']) && isset($_SESSION['users_email']) && isset($_SESSION['users_name']) && isset($_SESSION['users_level'])) { echo 'Terima kasih '.$_SESSION['users_name'].' kerana menggunakan system ini.'; session_destroy(); # Hapuskan PHP session yg dah diset sebelum ni. Maksudnya user kena login semula kalau nak access ke dashboard. } else echo 'Anda belum login ke system ataupon sudah logout.'; ?> <p> <input type="button" value="Balik ke login form" onclick="location='01_input.php';" /> </p> |
Untuk nak test benda ni, bolehlah masuk ke web browser gunakan
Password : password admin
Email : staff@test.com
Password : password staff
Entry kali ni adalah contoh paling asas untuk nak buat user authentication menggunakan PHP dan MySQL sebagai pendedahan awal kepada peminat-peminat PHP dengan kaedah yg aku rasa senang difahami. Terdapat beberapa cara lagi yg lebih advance dan secure, tapi kalau ceritakan pada newbie takut susah nak faham pulak.
Tamatlah untuk kali ni. Next nanti aku cuba ceritakan pasal system logs, iaitu rekod log untuk aktiviti-aktiviti yg berlaku dalam sesebuah system. Kalau boleh, cuba Subscribe atau register je kat blog ni menggunakan akaun Facebook masing-masing
, dan jugak YouTube channel aku untuk tutorial2 lain yg bakal menyusul nanti sebab mungkin ada sesetengah entry yg aku tak boleh kongsikan di Facebook atas sebab-sebab tertentu.Share the post "Belajar buat user login (asas) dalam PHP-MySQL"