Menerapkan Mekanisme Otentikasi Pengguna
Otentikasi pengguna sangat umum dalam aplikasi web modern. Ini adalah mekanisme keamanan yang digunakan untuk membatasi akses tidak sah (restrict unauthorized) khusus untuk member saja pada suatu situs tersebut.
Pada tutorial ini kita akan membuat sistem registrasi dan login sederhana menggunakan PHP dan MySQL. Tutorial ini terdiri dari dua bagian: di bagian pertama kita akan membuat form pendaftaran pengguna, dan di bagian kedua kita akan membuat form login, serta halaman pembuka dan skrip logout.
Membangun Sistem Registrasi
Di bagian ini kita akan membangun sistem pendaftaran yang memungkinkan pengguna untuk membuat akun baru dengan mengisi form web. Tapi, pertama kita perlu membuat tabel yang akan menampung semua data pengguna.
Langkah 1 : Membuat Tabel Database
CREATE TABLE users ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP );
Silakan periksa tutorial tentang pernyataan SQL CREATE TABLE untuk informasi terperinci tentang sintaks untuk membuat tabel dalam sistem database MySQL.
Langkah 2 : Membuat Config File
Setelah membuat tabel, kita perlu membuat skrip PHP untuk dapat terhubung ke server database MySQL. Mari kita membuat file bernama “config.php” dan memasukkan kode berikut di dalamnya.
<?php /* Database credentials. Assuming you are running MySQL server with default setting (user 'root' with no password) */ define('DB_SERVER', 'localhost'); define('DB_USERNAME', 'root'); define('DB_PASSWORD', ''); define('DB_NAME', 'demo'); /* Attempt to connect to MySQL database */ $link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME); // Check connection if($link === false){ die("ERROR: Could not connect. " . mysqli_connect_error()); } ?>
Jika kalian telah mengunduh contoh kode berorientasi objek atau PDO menggunakan tombol unduh, harap hapus teks “-oo-format” atau “-pdo-format” dari nama file sebelum menguji kode tersebut.
Catatan: Ganti kredensial sesuai dengan pengaturan server MySQL kalian sebelum menguji kode ini, misalnya, ganti nama basis data ‘demo‘ dengan nama basis data kalian sendiri, ganti nama pengguna ‘root‘ dengan nama pengguna basis data kalian sendiri, tentukan kata sandi basis data jika ada.
Langkah 3 : Membuat Form Registrasi
Mari kita buat file PHP lain “register.php” dan masukkan kode contoh berikut di dalamnya. Kode contoh ini akan membuat form web yang memungkinkan pengguna untuk mendaftar sendiri.
Skrip ini juga akan menghasilkan error jika pengguna mencoba mengirimkan form tanpa memasukkan nilai apa pun, atau jika nama pengguna yang dimasukkan oleh pengguna sudah digunakan oleh pengguna lain.
<?php // Include config file require_once "config.php"; // Define variables and initialize with empty values $username = $password = $confirm_password = ""; $username_err = $password_err = $confirm_password_err = ""; // Processing form data when form is submitted if($_SERVER["REQUEST_METHOD"] == "POST"){ // Validate username if(empty(trim($_POST["username"]))){ $username_err = "Please enter a username."; } else{ // Prepare a select statement $sql = "SELECT id FROM users WHERE username = ?"; if($stmt = mysqli_prepare($link, $sql)){ // Bind variables to the prepared statement as parameters mysqli_stmt_bind_param($stmt, "s", $param_username); // Set parameters $param_username = trim($_POST["username"]); // Attempt to execute the prepared statement if(mysqli_stmt_execute($stmt)){ /* store result */ mysqli_stmt_store_result($stmt); if(mysqli_stmt_num_rows($stmt) == 1){ $username_err = "This username is already taken."; } else{ $username = trim($_POST["username"]); } } else{ echo "Oops! Something went wrong. Please try again later."; } } // Close statement mysqli_stmt_close($stmt); } // Validate password if(empty(trim($_POST["password"]))){ $password_err = "Please enter a password."; } elseif(strlen(trim($_POST["password"])) < 6){ $password_err = "Password must have atleast 6 characters."; } else{ $password = trim($_POST["password"]); } // Validate confirm password if(empty(trim($_POST["confirm_password"]))){ $confirm_password_err = "Please confirm password."; } else{ $confirm_password = trim($_POST["confirm_password"]); if(empty($password_err) && ($password != $confirm_password)){ $confirm_password_err = "Password did not match."; } } // Check input errors before inserting in database if(empty($username_err) && empty($password_err) && empty($confirm_password_err)){ // Prepare an insert statement $sql = "INSERT INTO users (username, password) VALUES (?, ?)"; if($stmt = mysqli_prepare($link, $sql)){ // Bind variables to the prepared statement as parameters mysqli_stmt_bind_param($stmt, "ss", $param_username, $param_password); // Set parameters $param_username = $username; $param_password = password_hash($password, PASSWORD_DEFAULT); // Creates a password hash // Attempt to execute the prepared statement if(mysqli_stmt_execute($stmt)){ // Redirect to login page header("location: login.php"); } else{ echo "Something went wrong. Please try again later."; } } // Close statement mysqli_stmt_close($stmt); } // Close connection mysqli_close($link); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Sign Up</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css"> <style type="text/css"> body{ font: 14px sans-serif; } .wrapper{ width: 350px; padding: 20px; } </style> </head> <body> <div class="wrapper"> <h2>Sign Up</h2> <p>Please fill this form to create an account.</p> <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post"> <div class="form-group <?php echo (!empty($username_err)) ? 'has-error' : ''; ?>"> <label>Username</label> <input type="text" name="username" class="form-control" value="<?php echo $username; ?>"> <span class="help-block"><?php echo $username_err; ?></span> </div> <div class="form-group <?php echo (!empty($password_err)) ? 'has-error' : ''; ?>"> <label>Password</label> <input type="password" name="password" class="form-control" value="<?php echo $password; ?>"> <span class="help-block"><?php echo $password_err; ?></span> </div> <div class="form-group <?php echo (!empty($confirm_password_err)) ? 'has-error' : ''; ?>"> <label>Confirm Password</label> <input type="password" name="confirm_password" class="form-control" value="<?php echo $confirm_password; ?>"> <span class="help-block"><?php echo $confirm_password_err; ?></span> </div> <div class="form-group"> <input type="submit" class="btn btn-primary" value="Submit"> <input type="reset" class="btn btn-default" value="Reset"> </div> <p>Already have an account? <a href="login.php">Login here</a>.</p> </form> </div> </body> </html>
Output dari contoh di atas (mis. Form pendaftaran) akan terlihat seperti ini:

Pada contoh di atas, kita telah menggunakan fungsi PHP password_hash() untuk membuat hash kata sandi dari string kata sandi yang dimasukkan oleh pengguna (baris no-75). Fungsi ini menciptakan hash kata sandi menggunakan algoritma hashing satu arah yang kuat. Hal itu juga menghasilkan dan menerapkan kode acak secara otomatis ketika hashing kata sandi; ini berarti bahwa meskipun dua pengguna memiliki kata sandi yang sama, hash kata sandi mereka akan berbeda.
Pada saat login, kita akan memverifikasi kata sandi yang diberikan dengan hash kata sandi yang disimpan dalam database menggunakan fungsi PHP password_verify(), seperti yang ditunjukkan pada contoh berikut.
Kita telah menggunakan framework Bootstrap untuk membuat form layout dengan cepat dan indah. Silakan, cek bagian tutorial Bootstrap untuk mempelajari lebih lanjut tentang framework ini.
Membangun System Login
Di bagian ini kita akan membuat form login di mana pengguna dapat memasukkan nama pengguna dan kata sandi mereka. Ketika pengguna mengirimkan form input maka hal tersebut akan diverifikasi dengan yang disimpan dalam database, jika nama pengguna dan kata sandi cocok, pengguna diotorisasi dan diberikan akses ke situs, jika tidak maka upaya login akan ditolak.
Langkah 1 : Membuat Login Form
Mari kita buat file bernama “login.php” dan letakkan kode berikut di dalamnya.
<?php // Initialize the session session_start(); // Check if the user is already logged in, if yes then redirect him to welcome page if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){ header("location: welcome.php"); exit; } // Include config file require_once "config.php"; // Define variables and initialize with empty values $username = $password = ""; $username_err = $password_err = ""; // Processing form data when form is submitted if($_SERVER["REQUEST_METHOD"] == "POST"){ // Check if username is empty if(empty(trim($_POST["username"]))){ $username_err = "Please enter username."; } else{ $username = trim($_POST["username"]); } // Check if password is empty if(empty(trim($_POST["password"]))){ $password_err = "Please enter your password."; } else{ $password = trim($_POST["password"]); } // Validate credentials if(empty($username_err) && empty($password_err)){ // Prepare a select statement $sql = "SELECT id, username, password FROM users WHERE username = ?"; if($stmt = mysqli_prepare($link, $sql)){ // Bind variables to the prepared statement as parameters mysqli_stmt_bind_param($stmt, "s", $param_username); // Set parameters $param_username = $username; // Attempt to execute the prepared statement if(mysqli_stmt_execute($stmt)){ // Store result mysqli_stmt_store_result($stmt); // Check if username exists, if yes then verify password if(mysqli_stmt_num_rows($stmt) == 1){ // Bind result variables mysqli_stmt_bind_result($stmt, $id, $username, $hashed_password); if(mysqli_stmt_fetch($stmt)){ if(password_verify($password, $hashed_password)){ // Password is correct, so start a new session session_start(); // Store data in session variables $_SESSION["loggedin"] = true; $_SESSION["id"] = $id; $_SESSION["username"] = $username; // Redirect user to welcome page header("location: welcome.php"); } else{ // Display an error message if password is not valid $password_err = "The password you entered was not valid."; } } } else{ // Display an error message if username doesn't exist $username_err = "No account found with that username."; } } else{ echo "Oops! Something went wrong. Please try again later."; } } // Close statement mysqli_stmt_close($stmt); } // Close connection mysqli_close($link); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Login</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css"> <style type="text/css"> body{ font: 14px sans-serif; } .wrapper{ width: 350px; padding: 20px; } </style> </head> <body> <div class="wrapper"> <h2>Login</h2> <p>Please fill in your credentials to login.</p> <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post"> <div class="form-group <?php echo (!empty($username_err)) ? 'has-error' : ''; ?>"> <label>Username</label> <input type="text" name="username" class="form-control" value="<?php echo $username; ?>"> <span class="help-block"><?php echo $username_err; ?></span> </div> <div class="form-group <?php echo (!empty($password_err)) ? 'has-error' : ''; ?>"> <label>Password</label> <input type="password" name="password" class="form-control"> <span class="help-block"><?php echo $password_err; ?></span> </div> <div class="form-group"> <input type="submit" class="btn btn-primary" value="Login"> </div> <p>Don't have an account? <a href="register.php">Sign up now</a>.</p> </form> </div> </body> </html>
Output dari contoh di atas (mis. Form login) akan terlihat seperti ini:

Langkah 2 : Membuat Welcome Page
Berikut kode file “welcome.php” kita, tempat pengguna diarahkan setelah login berhasil.
<?php // Initialize the session session_start(); // Check if the user is logged in, if not then redirect him to login page if(!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true){ header("location: login.php"); exit; } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Welcome</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css"> <style type="text/css"> body{ font: 14px sans-serif; text-align: center; } </style> </head> <body> <div class="page-header"> <h1>Hi, <b><?php echo htmlspecialchars($_SESSION["username"]); ?></b>. Welcome to our site.</h1> </div> <p> <a href="reset-password.php" class="btn btn-warning">Reset Your Password</a> <a href="logout.php" class="btn btn-danger">Sign Out of Your Account</a> </p> </body> </html>
Jika data berasal dari sumber eksternal seperti form yang diisi oleh pengguna anonim, ada risiko bahwa itu mungkin berisi skrip berbahaya yang bermaksud untuk meluncurkan serangan skrip cross-site (XSS). Oleh karena itu, kalian harus menghindari data ini menggunakan fungsi PHP htmlspecialchars() sebelum menampilkannya di browser, sehingga tag HTML apa pun yang ada di dalamnya menjadi tidak berbahaya.
Misalnya, setelah mengeluarkan dari karakter khusus string <script>alert(“XSS”)</script> menjadi <script>alert(“XSS”)</script> yang dimana tidak akan dijalankan oleh browser.
Langkah 3 : Membuat Logout Script
Sekarang, mari kita buat file “logout.php“. Ketika pengguna mengklik pada log out atau sign out, skrip di dalam file ini akan menghancurkan (mengeluarkan) sesi dan mengarahkan pengguna kembali ke halaman login.
<?php // Initialize the session session_start(); // Unset all of the session variables $_SESSION = array(); // Destroy the session. session_destroy(); // Redirect to login page header("location: login.php"); exit; ?>
Menambahkan Fitur Reset Kata Sandi
Terakhir, di bagian ini kita akan menambahkan utilitas pengaturan ulang kata sandi ke sistem login kita. Dengan menggunakan fitur ini, pengguna yang masuk dapat langsung mengatur ulang kata sandi mereka sendiri untuk akun mereka.
<?php // Initialize the session session_start(); // Check if the user is logged in, if not then redirect to login page if(!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true){ header("location: login.php"); exit; } // Include config file require_once "config.php"; // Define variables and initialize with empty values $new_password = $confirm_password = ""; $new_password_err = $confirm_password_err = ""; // Processing form data when form is submitted if($_SERVER["REQUEST_METHOD"] == "POST"){ // Validate new password if(empty(trim($_POST["new_password"]))){ $new_password_err = "Please enter the new password."; } elseif(strlen(trim($_POST["new_password"])) < 6){ $new_password_err = "Password must have atleast 6 characters."; } else{ $new_password = trim($_POST["new_password"]); } // Validate confirm password if(empty(trim($_POST["confirm_password"]))){ $confirm_password_err = "Please confirm the password."; } else{ $confirm_password = trim($_POST["confirm_password"]); if(empty($new_password_err) && ($new_password != $confirm_password)){ $confirm_password_err = "Password did not match."; } } // Check input errors before updating the database if(empty($new_password_err) && empty($confirm_password_err)){ // Prepare an update statement $sql = "UPDATE users SET password = ? WHERE id = ?"; if($stmt = mysqli_prepare($link, $sql)){ // Bind variables to the prepared statement as parameters mysqli_stmt_bind_param($stmt, "si", $param_password, $param_id); // Set parameters $param_password = password_hash($new_password, PASSWORD_DEFAULT); $param_id = $_SESSION["id"]; // Attempt to execute the prepared statement if(mysqli_stmt_execute($stmt)){ // Password updated successfully. Destroy the session, and redirect to login page session_destroy(); header("location: login.php"); exit(); } else{ echo "Oops! Something went wrong. Please try again later."; } } // Close statement mysqli_stmt_close($stmt); } // Close connection mysqli_close($link); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Reset Password</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css"> <style type="text/css"> body{ font: 14px sans-serif; } .wrapper{ width: 350px; padding: 20px; } </style> </head> <body> <div class="wrapper"> <h2>Reset Password</h2> <p>Please fill out this form to reset your password.</p> <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post"> <div class="form-group <?php echo (!empty($new_password_err)) ? 'has-error' : ''; ?>"> <label>New Password</label> <input type="password" name="new_password" class="form-control" value="<?php echo $new_password; ?>"> <span class="help-block"><?php echo $new_password_err; ?></span> </div> <div class="form-group <?php echo (!empty($confirm_password_err)) ? 'has-error' : ''; ?>"> <label>Confirm Password</label> <input type="password" name="confirm_password" class="form-control"> <span class="help-block"><?php echo $confirm_password_err; ?></span> </div> <div class="form-group"> <input type="submit" class="btn btn-primary" value="Submit"> <a class="btn btn-link" href="welcome.php">Cancel</a> </div> </form> </div> </body> </html>