Selamat datang di tutorial singkat tentang cara membuat skrip pemulihan kata sandi yang terlupakan dengan PHP dan MySQL. Mengalami masalah dengan sistem yang memerlukan reset kata sandi manual?
Sistem pemulihan kata sandi otomatis umumnya melibatkan 3 langkah
- Pengguna mengakses halaman “lupa kata sandi”, memasukkan email, dan membuat permintaan pengaturan ulang kata sandi
- Sistem menghasilkan hash acak dan mengirimkan tautan konfirmasi ke email pengguna
- Terakhir, pengguna mengklik tautan konfirmasi. Sistem memverifikasi hash dan mengirimkan kata sandi baru ke pengguna
Itu mencakup ikhtisar proses, mari kita telusuri contoh aktual dalam panduan ini – Baca terus
ⓘ Saya telah menyertakan file zip dengan semua kode sumber di awal tutorial ini, jadi Anda tidak perlu menyalin-tempel semuanya… Atau jika Anda hanya ingin langsung masuk
DAFTAR ISI
UNDUH & CATATAN
Pertama, berikut adalah tautan unduhan ke kode contoh seperti yang dijanjikan
CATATAN CEPAT
- Buat basis data percobaan dan impor 1-database.sql
- Perbarui pengaturan basis data di 2-lib.php ke pengaturan Anda sendiri
- Anda mungkin juga ingin menelusuri -- (B) PASSWORD RESET
CREATE TABLE `password_reset` (
`user_id` bigint(20) NOT NULL,
`reset_hash` varchar(64) NOT NULL,
`reset_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `password_reset`
ADD PRIMARY KEY (`user_id`);0 di 2-lib.php dan memperbarui bagian berikut
- Templat email
- Pemeriksaan sesi/login pengguna
- Enkripsi kata sandi
- Luncurkan -- (B) PASSWORD RESET CREATE TABLE `password_reset` ( `user_id` bigint(20) NOT NULL, `reset_hash` varchar(64) NOT NULL, `reset_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `password_reset` ADD PRIMARY KEY (`user_id`);_2 di browser
SCREENSHOT
Baiklah, sekarang mari kita masuk ke detail pembuatan sistem pemulihan kata sandi yang terlupakan di PHP dan MYSQL
BAGIAN 1) DATABASE
1A) TABEL PENGGUNA
1-database. sql
Jika Anda belum memiliki basis data pengguna, inilah boneka yang akan kami gunakan dalam contoh ini
- -- (B) PASSWORD RESET CREATE TABLE `password_reset` ( `user_id` bigint(20) NOT NULL, `reset_hash` varchar(64) NOT NULL, `reset_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `password_reset` ADD PRIMARY KEY (`user_id`);3 Kunci primer, peningkatan otomatis
- -- (B) PASSWORD RESET CREATE TABLE `password_reset` ( `user_id` bigint(20) NOT NULL, `reset_hash` varchar(64) NOT NULL, `reset_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `password_reset` ADD PRIMARY KEY (`user_id`);4 Email pengguna, unik
- -- (B) PASSWORD RESET CREATE TABLE `password_reset` ( `user_id` bigint(20) NOT NULL, `reset_hash` varchar(64) NOT NULL, `reset_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `password_reset` ADD PRIMARY KEY (`user_id`);5 Nama lengkap pengguna
- -- (B) PASSWORD RESET CREATE TABLE `password_reset` ( `user_id` bigint(20) NOT NULL, `reset_hash` varchar(64) NOT NULL, `reset_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `password_reset` ADD PRIMARY KEY (`user_id`);6 Kata sandi pengguna. Perhatikan, tidak dienkripsi. Saya akan meninggalkan tautan di bawah untuk Anda tindak lanjuti
1B) TABEL RESET PASSWORD
1-database. sql
-- (B) PASSWORD RESET CREATE TABLE `password_reset` ( `user_id` bigint(20) NOT NULL, `reset_hash` varchar(64) NOT NULL, `reset_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `password_reset` ADD PRIMARY KEY (`user_id`);- -- (B) PASSWORD RESET CREATE TABLE `password_reset` ( `user_id` bigint(20) NOT NULL, `reset_hash` varchar(64) NOT NULL, `reset_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `password_reset` ADD PRIMARY KEY (`user_id`);3– Pengguna yang membuat permintaan "lupa kata sandi".
- -- (B) PASSWORD RESET CREATE TABLE `password_reset` ( `user_id` bigint(20) NOT NULL, `reset_hash` varchar(64) NOT NULL, `reset_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `password_reset` ADD PRIMARY KEY (`user_id`);8 – Hash acak yang dihasilkan saat membuat permintaan reset. Akan dikirim ke email pengguna untuk verifikasi;
- -- (B) PASSWORD RESET CREATE TABLE `password_reset` ( `user_id` bigint(20) NOT NULL, `reset_hash` varchar(64) NOT NULL, `reset_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `password_reset` ADD PRIMARY KEY (`user_id`);_9 – Waktu saat permintaan dibuat, untuk mencegah spam
BAGIAN 2) PERPUSTAKAAN RESET PASSWORD
2A) PERPUSTAKAAN DIINISIALISASI
2-lib. php
class Forgot { // (A) PROPERTIES private $valid = 900; // 15 mins = 900 secs private $plen = 8; // random password length private $pdo = null; // pdo object private $stmt = null; // sql statement public $error = ""; // errors, if any // (B) CONSTRUCTOR - CONNECT TO DATABASE function __construct () { $this->pdo = new PDO( "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); } // (C) DESTRUCTOR - CLOSE DATABASE CONNECTION function __destruct () { if ($this->stmt!==null) { $this->stmt = null; } if ($this->pdo!==null) { $this->pdo = null; } } // ... } // (J) DATABASE SETTINGS - @CHANGE TO YOUR OWN define("DB_HOST", "localhost"); define("DB_NAME", "test"); define("DB_CHARSET", "utf8mb4"); define("DB_USER", "root"); define("DB_PASSWORD", ""); // (K) NEW PASSWORD RECOVER OBJECT $_FORGOT = new Forgot();Perpustakaan dapat mengintimidasi beberapa pemula, jadi mari kita bahas dalam beberapa bagian
- (A) Beberapa properti kelas, hanya 2 yang "penting" di sini adalah -
- class Forgot { // (A) PROPERTIES private $valid = 900; // 15 mins = 900 secs private $plen = 8; // random password length private $pdo = null; // pdo object private $stmt = null; // sql statement public $error = ""; // errors, if any // (B) CONSTRUCTOR - CONNECT TO DATABASE function __construct () { $this->pdo = new PDO( "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); } // (C) DESTRUCTOR - CLOSE DATABASE CONNECTION function __destruct () { if ($this->stmt!==null) { $this->stmt = null; } if ($this->pdo!==null) { $this->pdo = null; } } // ... } // (J) DATABASE SETTINGS - @CHANGE TO YOUR OWN define("DB_HOST", "localhost"); define("DB_NAME", "test"); define("DB_CHARSET", "utf8mb4"); define("DB_USER", "root"); define("DB_PASSWORD", ""); // (K) NEW PASSWORD RECOVER OBJECT $_FORGOT = new Forgot();_0E. G. Jika pengguna membuat permintaan pengaturan ulang kata sandi pada pukul 10 pagi, itu harus diselesaikan dalam waktu 15 menit; . 15 pagi
- class Forgot { // (A) PROPERTIES private $valid = 900; // 15 mins = 900 secs private $plen = 8; // random password length private $pdo = null; // pdo object private $stmt = null; // sql statement public $error = ""; // errors, if any // (B) CONSTRUCTOR - CONNECT TO DATABASE function __construct () { $this->pdo = new PDO( "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); } // (C) DESTRUCTOR - CLOSE DATABASE CONNECTION function __destruct () { if ($this->stmt!==null) { $this->stmt = null; } if ($this->pdo!==null) { $this->pdo = null; } } // ... } // (J) DATABASE SETTINGS - @CHANGE TO YOUR OWN define("DB_HOST", "localhost"); define("DB_NAME", "test"); define("DB_CHARSET", "utf8mb4"); define("DB_USER", "root"); define("DB_PASSWORD", ""); // (K) NEW PASSWORD RECOVER OBJECT $_FORGOT = new Forgot();1 Panjang kata sandi baru, standarnya adalah 8 karakter
- (B, C, K) Ketika class Forgot { // (A) PROPERTIES private $valid = 900; // 15 mins = 900 secs private $plen = 8; // random password length private $pdo = null; // pdo object private $stmt = null; // sql statement public $error = ""; // errors, if any // (B) CONSTRUCTOR - CONNECT TO DATABASE function __construct () { $this->pdo = new PDO( "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); } // (C) DESTRUCTOR - CLOSE DATABASE CONNECTION function __destruct () { if ($this->stmt!==null) { $this->stmt = null; } if ($this->pdo!==null) { $this->pdo = null; } } // ... } // (J) DATABASE SETTINGS - @CHANGE TO YOUR OWN define("DB_HOST", "localhost"); define("DB_NAME", "test"); define("DB_CHARSET", "utf8mb4"); define("DB_USER", "root"); define("DB_PASSWORD", ""); // (K) NEW PASSWORD RECOVER OBJECT $_FORGOT = new Forgot();2 dibuat, konstruktor terhubung ke database secara otomatis. Destruktor menutup koneksi
- (J) Ingatlah untuk mengubah pengaturan basis data menjadi milik Anda sendiri
2B) PEMBANTU dan DAPATKAN FUNGSI
2-lib. php
// (D) HELPER - EXECUTE SQL QUERY function query ($sql, $data=null) { $this->stmt = $this->pdo->prepare($sql); $this->stmt->execute($data); } // (E) HELPER - SEND EMAIL function mail ($to, $subject, $body) { $head = implode("\r\n", ["MIME-Version: 1.0", "Content-type: text/html; charset=utf-8"]); return mail($to, $subject, $body, $head); } // (F) GET USER BY ID OR EMAIL function getUser ($id) { $this->query("SELECT * FROM `users` WHERE `user_".(is_numeric($id)?"id":"email")."`=?", [$id]); return $this->stmt->fetch(); } // (G) GET PASSWORD RESET REQUEST function getReq ($id) { $this->query("SELECT * FROM `password_reset` WHERE `user_id`=?", [$id]); return $this->stmt->fetch(); }Selanjutnya, kami memiliki banyak "fungsi pendek". Seharusnya cukup jelas
- class Forgot { // (A) PROPERTIES private $valid = 900; // 15 mins = 900 secs private $plen = 8; // random password length private $pdo = null; // pdo object private $stmt = null; // sql statement public $error = ""; // errors, if any // (B) CONSTRUCTOR - CONNECT TO DATABASE function __construct () { $this->pdo = new PDO( "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); } // (C) DESTRUCTOR - CLOSE DATABASE CONNECTION function __destruct () { if ($this->stmt!==null) { $this->stmt = null; } if ($this->pdo!==null) { $this->pdo = null; } } // ... } // (J) DATABASE SETTINGS - @CHANGE TO YOUR OWN define("DB_HOST", "localhost"); define("DB_NAME", "test"); define("DB_CHARSET", "utf8mb4"); define("DB_USER", "root"); define("DB_PASSWORD", ""); // (K) NEW PASSWORD RECOVER OBJECT $_FORGOT = new Forgot();_3 Fungsi pembantu untuk menjalankan kueri SQL
- class Forgot { // (A) PROPERTIES private $valid = 900; // 15 mins = 900 secs private $plen = 8; // random password length private $pdo = null; // pdo object private $stmt = null; // sql statement public $error = ""; // errors, if any // (B) CONSTRUCTOR - CONNECT TO DATABASE function __construct () { $this->pdo = new PDO( "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); } // (C) DESTRUCTOR - CLOSE DATABASE CONNECTION function __destruct () { if ($this->stmt!==null) { $this->stmt = null; } if ($this->pdo!==null) { $this->pdo = null; } } // ... } // (J) DATABASE SETTINGS - @CHANGE TO YOUR OWN define("DB_HOST", "localhost"); define("DB_NAME", "test"); define("DB_CHARSET", "utf8mb4"); define("DB_USER", "root"); define("DB_PASSWORD", ""); // (K) NEW PASSWORD RECOVER OBJECT $_FORGOT = new Forgot();_4 Helper berfungsi untuk mengirim email
- class Forgot { // (A) PROPERTIES private $valid = 900; // 15 mins = 900 secs private $plen = 8; // random password length private $pdo = null; // pdo object private $stmt = null; // sql statement public $error = ""; // errors, if any // (B) CONSTRUCTOR - CONNECT TO DATABASE function __construct () { $this->pdo = new PDO( "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); } // (C) DESTRUCTOR - CLOSE DATABASE CONNECTION function __destruct () { if ($this->stmt!==null) { $this->stmt = null; } if ($this->pdo!==null) { $this->pdo = null; } } // ... } // (J) DATABASE SETTINGS - @CHANGE TO YOUR OWN define("DB_HOST", "localhost"); define("DB_NAME", "test"); define("DB_CHARSET", "utf8mb4"); define("DB_USER", "root"); define("DB_PASSWORD", ""); // (K) NEW PASSWORD RECOVER OBJECT $_FORGOT = new Forgot();5 Dapatkan pengguna dengan ID atau email
- class Forgot { // (A) PROPERTIES private $valid = 900; // 15 mins = 900 secs private $plen = 8; // random password length private $pdo = null; // pdo object private $stmt = null; // sql statement public $error = ""; // errors, if any // (B) CONSTRUCTOR - CONNECT TO DATABASE function __construct () { $this->pdo = new PDO( "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); } // (C) DESTRUCTOR - CLOSE DATABASE CONNECTION function __destruct () { if ($this->stmt!==null) { $this->stmt = null; } if ($this->pdo!==null) { $this->pdo = null; } } // ... } // (J) DATABASE SETTINGS - @CHANGE TO YOUR OWN define("DB_HOST", "localhost"); define("DB_NAME", "test"); define("DB_CHARSET", "utf8mb4"); define("DB_USER", "root"); define("DB_PASSWORD", ""); // (K) NEW PASSWORD RECOVER OBJECT $_FORGOT = new Forgot();6 Dapatkan permintaan pengaturan ulang kata sandi dengan ID pengguna
2C) PERMINTAAN RESET
2-lib. php
// (H) PASSWORD RESET REQUEST function request ($email) { // (H1) ALREADY SIGNED IN - @CHANGE THIS TO YOUR OWN // ASSUMING YOU USE $_SESSION["USER"] if (isset($_SESSION["user"])) { $this->error = "You are already signed in."; return false; } // (H2) CHECK IF VALID USER $user = $this->getUser($email); if (!is_array($user)) { $this->error = "$email is not registered."; return false; } // (H3) CHECK PREVIOUS REQUEST (PREVENT SPAM) $req = $this->getReq($user["user_id"]); if (is_array($req)) { $expire = strtotime($req["reset_time"]) + $this->valid; $now = strtotime("now"); $left = $now - $expire; if ($left <0) { $this->error = "Please wait another ".abs($left)." seconds."; return false; } } // (H4) CHECKS OK - CREATE NEW RESET REQUEST $now = strtotime("now"); $hash = md5($user["user_email"] . $now); // random hash $this->query( "REPLACE INTO `password_reset` (`user_id`, `reset_hash`, `reset_time`) VALUES (?,?,?)", [$user["user_id"], $hash, date("Y-m-d H:i:s")] ); // (H5) SEND EMAIL TO USER - @CHANGE EMAIL TEMPLATE $mail = "<html><body><a href='//localhost/3b-reset.php?i={$user["user_id"]}&h={$hash}'>Click to reset</a></body></html>"; if ($this->mail($user["user_email"], "Password Reset", $mail)) { return true; } else { $this->error = "Error sending mail"; return false; } }Itu saja untuk proyek ini, dan ini adalah bagian kecil tentang beberapa tambahan yang mungkin berguna bagi Anda
HANYA BAREBONES – LAKUKAN PEKERJAAN RUMAH ANDA
Sebelum kode grandmaster ninja troll mulai memuntahkan asam – Ini adalah contoh dasar… Ada banyak hal yang perlu dan dapat dilakukan dengan lebih baik
- Kosmetik tentunya
- Keamanan – Tambahkan CAPTCHA untuk mencegah spam lebih lanjut
- Enkripsi kata sandi
- Terapkan kata sandi sementara, paksa pengguna untuk mengubahnya saat masuk
Jadi ya, saya hanya akan meninggalkan lebih banyak tautan di bawah yang mungkin dapat membantu Anda lebih lanjut
LINK dan REFERENSI
- Sistem Login Pengguna Sederhana Dengan PHP MySQL – Code Boxx
- Enkripsi & Dekripsi Kata Sandi PHP – Kotak Kodex
- Perbaiki "Email Tidak Terkirim" Di PHP - Code Boxx
- Google reCAPTCHA
TAMAT
Terima kasih telah membaca, dan kami telah sampai di akhir panduan ini. Saya harap ini membantu Anda untuk lebih memahami, dan jika Anda ingin berbagi sesuatu dengan panduan ini, jangan ragu untuk berkomentar di bawah ini. Semoga berhasil dan selamat membuat kode