Hampir semua website memerlukan login form. System login adalah bagian yang penting bagi sebuah website untuk menjaga keamanan data. Tutorial php membuat form login yang lebih aman ini akan menjelaskan bagaimana cara memdeteksi akses berbeda. Login di php menggunakan session / sesi yang memerlukan ID session yang dikirim ke browser berupa cookie. Jika cookie ini berhasil dicuri maka sesorang akan bisa mengakses halaman admin tanpa perlu login. Tutorial membuat form login ini akan menjelaskan salah satu cara untuk menangkalnya. Tutorial php ini juga dilengkapi video tutorial yang bisa dilihat di channel Youtube MyPHPtutorials.
Video tutorial membuat form login yang lebih aman
Berikut langkah langkah untuk membuat form login yang lebih aman.
Buatlah tabel users untuk dengan struktur seperti di bawah (bisa menggunakan phpMyAdmin atau yang lain).
Kolom | Tipe Data | Keterangan |
---|---|---|
id | integer | primary key, auto increment |
username | varchar | unique |
password | varchar | |
salt | varchar | karakter acak untuk perkuat password |
aktif | tinyint | 1 = user aktif, 0 tidak aktif |
nama | varchar |
Kolom lain bisa ditambahkan sesuai dengan kebutuhan
Buatlah file cek-akses.php
yang akan digunakan untuk validasi akses user. Apakah sudah login atau tidak. Variable $_SERVER
(selengkapnya lilhat di https://php.net/$SERVER) akan digunakan untuk memvalidasi siapa browser dan alamat IP yang digunakan user. Jika browser dan alamat IP berubah makan user harus login lagi.
<?php
session_start();
if(!isset($_SESSION['browser']) || !isset($_SESSION['ip']) || empty($_SESSION['user'])) {
header("Location: login.php");
exit;
}
if ($_SESSION['browser'] != md5($_SERVER['HTTP_USER_AGENT']) || $_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) {
header("Location: login.php");
exit;
}
Paling pertama yang harus dilakukan adalah memulai session dengan fungsi session_start()
. Kemudian jika tidak ada informasi browser, IP atau user di session arahkan user ke halaman login. Selanjutnya cek apakah informasi browser yang disimpan di session sama dengan $_SERVER['HTTP_USER_AGENT']
dan alamat IP sama dengan $_SERVER['REMOTE_ADDR']
. Jika misalnya cookie dicuri, maka tidak akan bisa digunakan karena alamat IP pencuri pasti berbeda. Kemudian file ini bisa di-include di file yang harus diakses setelah login seperti di bawah.
<?php
include_once "cek-akses.php";
?>
<!DOCTYPE html>
<html>
<head>
<title>Admin</title>
<style>
table {
border: 1px solid #ddd;
border-collapse: collapse;
width: 50%;
}
table td, table th {
border: 1px solid #ddd;
padding: 8px
}
</style>
</head>
<body>
<h1>Selamat Datang</h1>
<p>
<a href="tambah-user.php">Tambah User</a> | <a href="logout.php">Logout</a>
</p>
<table>
<thead>
<tr>
<th>ID</th>
<th>Nama</th>
<th>Aktif</th>
</tr>
</thead>
<tbody>
<?php
$pdo = include "koneksi.php";
$query = $pdo->prepare("select id,nama,aktif from users");
$query->execute();
while($user = $query->fetch()) {
?>
<tr>
<td><?php echo $user['id'];?></td>
<td><?php echo $user['nama'];?></td>
<td><?php echo $user['aktif'];?></td>
</tr>
<?php }?>
</tbody>
</table>
</body>
</html>
Sekarang buatlah file login.php
dan buat html form login seperti di bawah, dengan 2 input username dan password
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Please login</h1>
<?php
if ($gagal) {
echo '<h2 style="color:red">Username atau password salah</h2>';
}
?>
<form method="POST" action="">
<div>
<div>Username</div>
<p>
<input type="text" name="username"/>
</p>
</div>
<div>
<div>Password</div>
<p>
<input type="password" name="password"/>
</p>
</div>
<button type="submit">Login</button>
</form>
</body>
</html>
Kemudian di bagian paling atas file tambahkan kode php untuk membuat validasi password user.
<?php
session_start();
$gagal = false;
if(!empty($_POST)) {
$pdo = include "koneksi.php";
$query = $pdo->prepare("select * from users where username=:username");
$query->execute(array('username' => $_POST['username']));
$user = $query->fetch();
if (!$user) {
$gagal = true;
} elseif($user['aktif'] != 1 || $user['password'] != sha1($_POST['password'].$user['salt'])){
$gagal = true;
} else {
$_SESSION['browser'] = md5($_SERVER['HTTP_USER_AGENT']);
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['user'] = array(
'id' => $user['id'],
'nama' => $user['nama']
);
header("Location: admin.php");
exit;
}
}
?>
Kembali paling atas mulai session dengan session_start()
. Kemudian jika user mencoba login dengan mengklik tombol login, buat koneksi ke database dengan. File koneksi.php
untuk membuat koneksi ke datatabase seperti kode di bawah. Di baris ke-6 sampai ke-8 kita cari data user dengan username yang telah dimasukkan user. Jika tidak tidak ditemukan (baris ke-9), set $gagal
dengan true
. Begitu juga jika user tidak aktif, atau password tidak sama dengan yang di database. Perhatikan baris ke-11.
$user['password'] != sha1($_POST['password'].$user['salt'])
password yang di input user digabungkan dengan data salt
dari database (lebih lengkah penjelasaany di bawah di form tambah user). Terakhir jika password benar dan user aktif maka simpan informasi browser, IP dan user ke session.
<?php
// file koneksi.hp
$host = "mysql";
$username = "root";
$password = "change_me";
$database = "tutorials";
return new PDO("mysql:host=$host;dbname=$database", $username, $password, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
Setelah berhasil login maka user harus bisa logout. Membuat logout lebih sederhana yaitu dengan menghapus semua informasi session yang telah dibuat di form login seperti kode php di bawah dalam file logout.php
.
<?php
session_start();
unset($_SESSION['browser']);
unset($_SESSION['ip']);
unset($_SESSION['user']);
session_regenerate_id();
session_destroy();
header("Location: login.php");
Baris ke-6 digunakan untuk membuat ID session yang baru agar ID yang lama tidak bisa digunakan lagi. Dan baris ke-7 untuk membuang session yang sebelumnya.
Pertama tama buatlah file tambah-user.php
dan tambahkan form untuk tambah user seperti di bawah.
<!DOCTYPE html>
<html>
<head>
<title>Tambah User</title>
</head>
<body>
<h1>Tambah User</h1>
<?php
if ($error) {
echo '<h5 style="color:red">'.$error.'</h5>';
}
?>
<form method="POST" action="">
<div>
<div>Nama</div>
<p>
<input type="text" name="nama"/>
</p>
</div>
<div>
<div>Username</div>
<p>
<input type="text" name="username"/>
</p>
</div>
<div>
<div>Password</div>
<p>
<input type="password" name="password"/>
</p>
</div>
<div>
<div>Ulang Password</div>
<p>
<input type="password" name="password2"/>
</p>
</div>
<div>
<div>Aktif</div>
<p>
<input type="hidden" name="aktif" value="0"/>
<input type="checkbox" name="aktif" value="1"/>
</p>
</div>
<button type="submit">Simpan</button>
</form>
</body>
</html>
Setelah itu tambahkan kode php untuk menambah user di bagian paling atas seperti di bawah.
<?php
include_once "cek-akses.php";
$error = '';
if (!empty($_POST)) {
if($_POST['password2'] != $_POST['password']) {
$error = 'Password dan ulang password harus sama';
} else {
try {
$pdo = include "koneksi.php";
$query = $pdo->prepare("insert into users (username, password, salt, nama, aktif) values(:username, :password,:salt,:nama,:aktif)");
$string = str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
$salt = sha1(substr($string, 0, 8).time().rand());
$query->execute(array(
'username' => $_POST['username'],
'password' => sha1($_POST['password'].$salt),
'salt' => $salt,
'nama' => $_POST['nama'],
'aktif' => $_POST['aktif']
));
header("Location: admin.php");
exit;
} catch (Exception $e) {
$error = $e->getMessage();
}
}
}
?>
Baris 5-7 kita lakukan validasi password dan ulang password harus sama. Di baris 11-12 kita membuat nilai salt
menggunakan fungsi str_shuffle
, time
dan juga rand
agar mendapatkan karakter acak yang lebih baik. Baris 13-19 digunakan untuk menyimpan data user. Perhatikan baris ke-15, 'password' => sha1($_POST['password'].$salt)
. Password disimpan dengan gabungan dengan password yang diisi oleh user dan juga salt dengan begitu password yang tersimpan di database tidak pernah sama. Walaupun user input data yang sama. Password juga disimpan dalam bentuk SHA1 sehingga tidak bisa dilihat dengan kasat mata. Dengan 2 kombinasi itu password akan susah ditebak seandainya database berhasil dicuri.
Dalam tutorial php membuat form login yang lebih aman ini telah dijelaskan cara untuk menangkal pencurian cookie, dengan memvalidasi browser dan alaman IP user. Kemudian password disimpan menggunakan SHA1 sehingga tidak bisa dilihat dengan kasat mata. Password juga dikombinasikan dengan salt
nilai acak yang membuat password yang disimpan di database tidak pernah sama walaupun user memasukkan password yang sama. Sehingga jika terjadi pencurian database password akan sudah ditebak. Perlu dicatat bahwa cara ini tidak benar benar 100% memberi jaminan keamanan. SHA1 dapat dipecahkan menggunakan super komputer. Untuk mengingkatkannya bisa menggunakan bcrypt namun lebih lambat dari pada SHA1. Pastikan juga website anda tidak memiliki masalah XSS. Sehingga cookie tidak mudah dicuri. Ikuti recomendasi dari setting cookie di php. Minimal set cookie SameSite=Lax httponly secure
dan gunakan SSL di website Anda.