Как сделать регистрацию для своего сайта на PHP + MySQL?

Всем привет! У людей, которые начинают осваивать язык PHP, почти сразу возникает вопрос - "как сделать регистрацию на сайте?". Иногда даже - "Как сделать правильно?".

Логика данного процесса такова:

  • Человек зашел на сайт, захотел зарегистрироваться
  • Ввел свои данные в специальную форму
  • Сервер проверил, что такого пользователя еще нет с создал запись о нем
  • После этого пользователь вводит данные в другую формя для авторизации
  • Сервер проверяет данные на совпадение и сохраняет куку с маркером к пользователю на пк.
  • Далее пользователь считается авторизованным пока кука не удалиться

Это грубая схема работы регистрации/авторизации для сайта.

Конечно, для реализации какой либо регистрации необходим хостинг который поддерживает PHP, а так же MySql. Иначе вы просто не сможете сохранить данные о пользователе, соответственно и зарегистрироваться он не сможет.

Если подумать, то можно сделать все достаточно просто. Можно даже обойтись без базы данных (хотя я не рекомендую так делать), однако остается резонный вопрос - "А безопасно ли это будет работать?".

И это очень правильный вопрос. Если делать простую проверку существования и схожести данных в базе данных, можно напороться на весьма неприятную уязвимость. С помощью этой уязвимости можно удалить всю базу, поменять пароли, заменить какие-либо данные на сайте, согласитесь, очень не приятно.

Как обезопасить свой сайт

Для безопасности вашего сайта, важны несколько пунктов.

  • Проще всего делать сайт с единой точкой входа. Коротко об этом поговорим чуть ниже.
  • Экранировать все запросы. Сделать это можно в ручную или же с помощью подготовленных запросов.
  • Ограничивать данные которые может ввести пользователь

Единая точка входа

Единая точка входа - это когда все запросы проходят через один главный скрипт. На первый взгляд может показаться, что это не удобно, однако, это не так. Такой подход дает множество преимуществ.

К примеру, файл проверки авторизации можно подключить один раз в одном месте и забыть, что нужно где-то это проверять. Можно ограничить доступ к разным частям сайта любого пользователя. Ни кто не сможет зайти на какую-то скрытую страницу, просто подобрав адрес. И т.д.

Подробнее разберем эту тему в другой статье, а пока давайте создадим фундамент нашего сайта.

В корне сайта нужно создать файл ".htaccess" и прописать в нем правила переадресации.


RewriteEngine On
RewriteCond %{REQUEST_URI} !(png|gif|jpg|jpeg|css|js)$
RewriteRule .* index.php [L,QSA]

Этот файл даст хостингу понять, что мы включаем переадресацию на index.php всех запросов, кроме картинок, стилей css и js скриптов.

Экранизация запросов

Для того что-бы злоумышленник не смог встроить свой запрос для нашей базы и любом поле, все поля и запросы нужно экранировать. Делается это несколькими способами.

  • Ручная проверка данных
  • С помощью подготовленных запросов

Под ручной проверкой подразумевается, что все данные будут проходить фильтр из блоков "if else", а так же через специальные функции которые удаляют спец-символы.

<?php 
	if ($_POST['login']!='' && $_POST['pass']!=''){//проверяем что поля не пустые
		if (strlen($_POST['login'])<=30 && strlen ($_POST['pass'])<= 30){//проверяем чтоб логин и пароль был меньше 30 символов
			$login = htmlspecialchars($_POST['login']);//убираем спецсимволы
			$pass = htmlspecialchars($_POST['pass']);//убираем спецсимволы

			$login = mysql_real_escape_string($login);//еще одна экранизация
			$pass = mysql_real_escape_string($pass);//еще одна экранизация

			//ну и тут уже можно делать запрос в базу. Пароли лучше всего хранить в двойном md5
		}
	}
?>

Подготовленные запросы, делают все безопаснее и понятнее при чтении кода. Совершить SQL-инъекцию уже не получиться и проверять данные не обязательно, однако рекомендуется.

login.php

<?php

	if ($_POST['login']=='' || $_POST['password']=='') echo 
		'<!DOCTYPE html>
			<html lang="ru">
			<head>
			    <meta charset="UTF-8">
			    <title>Авторизация</title>
			</head>
			<body>
			 
				<form action="login" method="POST">
					<p>логин
				    <input type="text" name="login" id="login"></p>
				    <p>пароль
				    <input type="password" name="password" id="password"></p>
				    <input type="submit" id="button" value="Войти">
				</form>
				<p><a href="registration">Регистрация</a> </p>
			                
			</body>
			</html>';
	else{
		//вот так данные можно отправлять без проверки вовсе, ни чего очень плохого случиться не должно. 
		//PDO все заэкранирует и превратит в текст. 
		//Можно разве что проверять длинну текста и какие то специфическиие данные

		$sql = "SELECT * FROM users WHERE login=:login AND password=:pass";//Формируем запрос без данных
		$result = $pdo->prepare($sql);
		$result->bindvalue(':login', $_POST['login']);	//Заполняем данные
		$result->bindvalue(':pass', md5(md5($_POST['password'])));	//Заполняем данные. Пароли хранить в открытом виде, дело такое. Поэтому двойной md5)
		$result->execute( );							//Выполняем запросы
		$result = $result->fetchAll();					//переводим обьект ПДО в массив данных, для удобной работы

		if (count($result)>0) {//Если база вернула 1 значение, значит и логин и пароль совпали. отлично
			echo '<meta charset="UTF-8">Ура! Мы авторизировались!'; 
			$_SESSION['user'] = $result[0];//сохраняем обьект пользователя в сессии
			
		}else echo '<meta charset="UTF-8">Логин или пароль не верный или пользователь не существует';
	}
?>

Давайте теперь сохраним этот файл. Так как будем его использовать дальше. Назовем его к примеру login.php и положим его в корень сайта.

Index.php, обработка запросов

Это тот самый файл через который будут проходить все запросы. В нем нужно описать логику доступа к страницам, маршрутизацию.

index.php

<?php
session_start();
include("bd.php");
$page = $_SERVER['REQUEST_URI'];

if (isset($_SESSION['user'])){								//если пользователь авторизован
	echo '<meta charset="UTF-8">Привет, '.$_SESSION['user']['login'].'!';
}else{		
	switch($page){
		case "/login":
			include("login.php");
			break;
		case "/registration":
			include("registration.php");
			break;
		default:
			include("login.php");
			break;
	}							//перекидываем на страницу регистрации авторизации
}

?>

Маршрутный файл мы написали. Давайте теперь подключим базу данных.

Для начала создадим базу

Обычно это делается через PhpMyAdmin. Создаем новую базу данных и назовем к примеру "reg".

Создание базы данных в MySql

После создания она появиться чуть ниже, нажмите на нее. Жмем "создать таблицу". Далее нужно указать какие поля будем использовать. К примеру у нас будет только 3 поля: id, login, password.

создание таблицы базы данных mySql

Id будет цифровым, два остальных текстовыми полями. На id нужно нажать на A_I (чтобы цифра сама увеличивалась). Собственно все, база для теста создана.

Подключение к MySql в PDO

bd.php

<?php

	$db_name = "reg";

	$login = "root";
	$password = "";
	
	
	try{
		$pdo = new PDO("mysql:host=localhost;dbname=".$db_name.";charset=utf8",$login, $password);
		$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

	}catch(PDOException $e){
		$Log_File = "log.txt";
		file_put_contents($Log_File, date("Y-m-d H:i:s")." -//- ".$e->getMessage().PHP_EOL, FILE_APPEND | LOCK_EX);	
		echo '<meta charset="UTF-8">Ошибка базы данных';
	}

?>

Тут вроде бы все просто, подключаемся к базе данных, а в случае ошибок выводим сообщение и пишем в лог файл.

Регистрация для сайта на PHP

Логиниться мы уже можем, однако пользователи еще не существуют, нужно создать файл, который будет создавать новых счастливых пользователей для вашего сайта.

registration.php

<?php

	if ($_POST['login']=='' || $_POST['password']=='') echo 
		'<!DOCTYPE html>
			<html lang="ru">
			<head>
			    <meta charset="UTF-8">
			    <title>Регистрация</title>
			</head>
			<body>
			 
				<form action="registration" method="POST">
					<p>логин
				    <input type="text" name="login" id="login"></p>
				    <p>пароль
				    <input type="password" name="password" id="password"></p>
				    <input type="submit" id="button" value="Зарегистрироваться">
				</form>
				<p><a href="login">Авторизация</a> </p>
			                
			</body>
			</html>';
	else{
		//вот так данные можно отправлять без проверки вовсе, ни чего очень плохого случиться не должно. 
		//PDO все заэкранирует и превратит в текст. 
		//Можно разве что проверять длинну текста и какие то специфическиие данные
		try{
			$sql = "INSERT INTO  `users` (`id` ,`login` ,`password`)
					VALUES (
					NULL ,  :login,  :pass
					);";//Формируем запрос без данных
			$result = $pdo->prepare($sql);
			$result->bindvalue(':login', $_POST['login']);	//Заполняем данные
			$result->bindvalue(':pass', md5(md5($_POST['password'])));	//Заполняем данные. Пароли хранить в открытом виде, дело такое. Поэтому двойной md5)
			$result->execute( );							//Выполняем запросы

			echo '<meta charset="UTF-8">Регистрация успешна!';
		}catch(PDOException $e){
			$Log_File = "log.txt";
			file_put_contents($Log_File, date("Y-m-d H:i:s")." -//- ".$e->getMessage().PHP_EOL, FILE_APPEND | LOCK_EX);				
			echo '<meta charset="UTF-8">Ошибка регистрации';
		}

			
		}
?>

Итоги

Мы сделали простейшую регистрацию с PDO или же подготовленными запросами. Сейчас нет проверок на существование пользователей, то есть можно создать несколько одинаковых логинов, что ни есть хорошо, конечно же, но для понимания принципов сойдет. Так же, перед каждым отдельным сообщением пришлось добавить "

В реальном проекте нужно добавлять отдельную шапку и там прописать это один раз и забыть.

Вы наверное заметили что мы не сделали страницу выхода из аккаунта. Да, так и есть, попробуйте сделать ее сами. Оставлю только подсказку, сессию можно удалить с помощью функции
"session_destroy()", что будет означать что мы вышли из аккаунта.

3.65/5 (27)

Оцените