Xác thực người dùng, tính năng đăng ký đăng nhập trong PHP
- 12-03-2023
- Toanngo92
- 0 Comments
Xác thực người dùng là một tác vụ quan trọng trong bất kỳ ứng dụng Web nào để đảm bảo rằng những người không được ủy quyền sẽ không truy cập được vào ứng dụng. Trong quá trình này, dữ liệu đăng nhập do người dùng nhập vào được so sánh và khớp với dữ liệu có trong cơ sở dữ liệu của máy chủ. Sử dụng cơ chế bảo mật này, có thể hạn chế người dùng trái phép truy cập các công cụ hoặc ứng dụng Web.
Mục lục
Xác thực người dùng PHP với MySQL
Quá trình xác thực người dùng giúp xác thực người dùng. Việc xác thực được thực hiện bằng cách sử dụng các khóa, mã thông báo hoặc thông tin đăng nhập nhất định. Trong trường hợp người dùng nhập thông tin đăng nhập được duyệt thì quá trình xác thực được coi là thành công, ngược lại coi như không thành công. Nếu quá trình thành công, người dùng được phép truy cập vào hệ thống.
Quá trình tạo hệ thống xác thực người dùng trong PHP bao gồm các bước chính:
- Tạo bảng trong database
- Tạo file kết nối với mysql để sử dụng chung trong các tình huống truy vấn
- Phát triển register form để tạo tính năng đăng ký
- Phát triển login form để người dùng truyền thông tin xác thực lên máy chủ bằng php
- Tạo câu truy vấn để so sánh dữ liệu của người dùng với database
Ví dụ dưới đây là một tình huống tạo bảng users trong database, tạo file kết nối mysql phát triển register form và login form để tạo và xác thực thông tin người dùng.
Tạo bảng users trong database
Tạo một file tùy chỉnh tên ví dụ createdatabase.php
<?php
$conn = new mysqli("localhost", "root", "", null);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "CREATE database IF NOT EXISTS mydb";
$result = $conn->query($sql);
if ($result) {
echo "Database created successfully";
} else {
echo "Error creating database: " . $conn->error;
}
$conn->select_db('mydb');
$sql = "CREATE table IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(30) NOT NULL,
password VARCHAR(40) NOT NULL,
email VARCHAR(50) NOT NULL,
fullname varchar(50),
phone varchar(11),
avatar varchar(100)
)";
$result = $conn->query($sql);
if ($result) {
echo "Table users created successfully";
} else {
echo "Error creating table: " . $conn->error;
}
Truy cập vào file theo đúng cấu trúc đường dẫn để tạo database.
Tạo file kết nối mysql
Tạo file kết nối SQL để nạp vào các file có nghiệp vụ tương tác với mySQL
<?php
$conn = new mysqli('localhost', 'root', '', 'mydb');
Tạo register form
Tạo một file tùy chỉnh tên ví dụ register.php
<?php
include 'connect.php';
$errors = [];
if (isset($_POST['register'])) {
$username = htmlspecialchars($_POST['username']);
$password = htmlspecialchars($_POST['password']);
$password_confirm = htmlspecialchars($_POST['password_confirm']);
$fullname = htmlspecialchars($_POST['fullname']);
$email = htmlspecialchars($_POST['email']);
$phone = htmlspecialchars($_POST['phone']);
if (empty($username)) {
$errors['username'] = 'Username is required';
}
if (strlen($username) < 4 || strlen($username) > 20) {
$errors['password_len'] = 'Username must be between 4 and 20 characters';
}
if (empty($password)) {
$errors['password'] = 'Password is required';
}
if (strlen($password) < 4 || strlen($password) > 20) {
$errors['password_len'] = 'Password must be between 4 and 20 characters';
}
if ($password != $password_confirm) {
$errors['password_confirm'] = 'Password does not match';
}
if (empty($email)) {
$errors['email'] = 'Email is required';
}
if (count($errors) == 0) {
$sql = sprintf("INSERT into users values(null,'%s','%s','%s','%s','%s')", $username, sha1($password), $email, $fullname, $phone);
$result = $conn->query($sql);
if ($result) {
header('Location: login.php?registersuccess=1');
} else {
if ($conn->errno == 1062) {
if (strpos($conn->error, 'username') != false) {
$errors['username_duplicate'] = 'Username already exists';
}
if (strpos($conn->error, 'email') != false) {
$errors['email_duplicate'] = 'Email already exists';
}
}else{
echo "Error: " . $conn->error;
}
// echo "Error: " . $conn->error;
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<section class="container">
<div class="row">
<div class="col-12">
<form id="regsiter_form" method="post">
<p class="text-center">Register a new membership</p>
<div class="form-group">
<input type="text" class="form-control" id="fullname" name="fullname" placeholder="Enter fullname">
</div>
<div class="form-group">
<input type="text" class="form-control" id="username" name="username" placeholder="Enter username" required minlength="4" maxlength="20">
</div>
<div class="form-group">
<input type="email" class="form-control" id="email" name="email" placeholder="Enter email" required>
</div>
<div class="form-group">
<input type="text" pattern="[0-9]{10,11}" class="form-control" id="phone" name="phone" placeholder="Enter phone" required>
</div>
<div class="form-group">
<input type="password" class="form-control" id="password" name="password" placeholder="Enter password" required minlength="4" maxlength="20">
</div>
<div class="form-group">
<input type="password" class="form-control" id="password_confirm" name="password_confirm" placeholder="Retype password" required minlength="4" maxlength="20">
</div>
<div class="form-group">
<input type="checkbox" name="aggree" /> I agree to the terms
</div>
<input type="hidden" name="register" value="1" />
<input type="submit" value="Regsiter" name="register_btn" class="btn btn-primary" />
<a href="login.php">I already have a membership</a>
<?php
foreach ($errors as $error) {
echo '<p class="text-danger">' . $error . '</p>';
}
?>
</form>
</div>
</div>
</section>
<script>
$('#password_confirm').on('keyup', function(e) {
if ($('#password').val() != $('#password_confirm').val()) {
$('#password_confirm').addClass('is-invalid');
} else {
$('#password_confirm').removeClass('is-invalid');
}
});
$('#regsiter_form').on('submit', function(e) {
e.preventDefault();
form = e.target;
if ($('input[name=aggree]').is(':checked')) {
if ($('#password').val() == $('#password_confirm').val()) {
form.submit();
} else {
alert('Password not match');
}
} else {
alert('You must agree to the terms');
}
});
</script>
</body>
</html>
Tạo login form
<?php
session_start();
if(isset($_SESSION['username'])){
header('location: index.php');
}
require_once 'connect.php';
if (isset($_GET['registersuccess'])) {
echo '<div class="alert alert-success" role="alert">
Register success
</div>';
}
$errors = [];
if(isset($_POST['register_btn'])){
$username = htmlspecialchars($_POST['username']);
$conn->real_escape_string($username);
$password = htmlspecialchars($_POST['password']);
$conn->real_escape_string($password);
if(empty($username)){
$errors['username'] = 'Username is required';
}
if(empty($password)){
$errors['password'] = 'Password is required';
}
if(strlen($username) < 4 || strlen($username) > 20){
$errors['username_len'] = 'Username must be between 4 and 20 characters';
}
if(strlen($password) < 4 || strlen($password) > 20){
$errors['password_len'] = 'Password must be between 4 and 20 characters';
}
$sql = sprintf("SELECT * FROM users WHERE username = '%s' AND password = '%s'", $username,sha1($password));
$result = $conn->query($sql);
if($result->num_rows > 0){
// setcookie('username', $username, time() + (86400 * 30), "/");
$_SESSION['username'] = $username;
header('Location: index.php');
}else{
$errors['login_fail'] = 'Login fail';
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<section class="container">
<div class="row">
<div class="col-12">
<form id="login_form" method="post">
<p class="text-center">Login form</p>
<div class="form-group">
<input type="text" class="form-control" id="username" name="username" placeholder="Enter username" required minlength="4" maxlength="20">
</div>
<div class="form-group">
<input type="password" class="form-control" id="password" name="password" placeholder="Enter password" required minlength="4" maxlength="20">
</div>
<input type="submit" value="Login" name="register_btn" class="btn btn-primary" />
<?php
foreach($errors as $error){
echo '<div class="alert alert-danger" role="alert">
'.$error.'
</div>';
}
?>
</form>
</div>
</div>
</section>
</body>
</html>
Tạo file index.php thông báo cho người dùng khi đăng nhập thành công:
<?php
session_start();
if(isset($_SESSION['username'])){
echo 'hello'.$_SESSION['username'];
}else{
header('location: login.php');
}
require_once 'connect.php';
Bài tập
Bài tập:
Scenario: Hệ thống check-in sự kiện (Event Check-in) cho khách tham dự.
Part 1: Database + Connection File (4 points)
Tạo file db.php dùng include/require:
-
Kết nối MySQL, lưu connection vào biến phù hợp. (1đ)
-
Tạo DB
event_portalnếu chưa có. (1đ) -
Tạo bảng
attendeesnếu chưa có: (1đ)
-
CODEVARCHAR(30) UNIQUE -
FULLNAMEVARCHAR(150) -
PHONEVARCHAR(15) -
CHECKED_INTINYINT(1) DEFAULT 0
-
Nếu lỗi, dừng và in thông báo lỗi. (1đ)
Part 2: Cookie – Remember Last Guest Code (4 points)
Tạo trang enter-code.php:
-
Form nhập
guest_code(POST về chính trang). (1đ) -
Khi submit, lưu cookie
last_guest_code= mã vừa nhập (hết hạn 24h). (1đ) -
Nếu cookie tồn tại, auto-fill input bằng giá trị cookie và hiển thị “Last code: …”. (2đ)
Part 3: Session – Check-in Flow (4 points)
Tạo trang checkin.php:
-
Nhận
guest_codetừ form (POST). Nếu rỗng → báo lỗi + hiện lại form. (1đ) -
Nếu
guest_codetồn tại trong DB:
-
Lưu session
current_attendeegồm: code, fullname, phone (dạng array) (1đ) -
Hiển thị trang “Check-in confirmation” với thông tin khách. (1đ)
-
Nếu không tồn tại → báo “Invalid guest code” + hiện lại form. (1đ)
Part 4: Update DB + Session Message (4 points)
Tạo nút Confirm Check-in trên trang xác nhận:
-
Khi bấm Confirm:
-
Cập nhật
CHECKED_IN = 1cho đúngCODE. (2đ) -
Lưu session flash message:
checkin_status = "SUCCESS"(1đ) -
Redirect sang
attendees.php(1đ)
Part 5: Attendees List + Cookie Filter (4 points)
Tạo trang attendees.php hiển thị danh sách:
-
Table gồm: Code, Fullname, Phone, Checked-in. (2đ)
-
Nếu session
checkin_status= SUCCESS → hiển thị message thành công rồi xóa session đó. (1đ) -
Có checkbox “Show checked-in only”.
-
Nếu tick: set cookie
filter_checkedin=1(expire 1h) -
Nếu bỏ tick: set cookie
filter_checkedin=0 -
Load trang sẽ đọc cookie để quyết định lọc danh sách. (1đ)


