mirror of
https://github.com/matroskin978/simple-auth.git
synced 2026-01-12 13:59:29 +00:00
Initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.idea
|
||||
4
incs/config.php
Normal file
4
incs/config.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
define("ROOT", dirname(__DIR__));
|
||||
const VIEWS = ROOT . '/views';
|
||||
16
incs/db.php
Normal file
16
incs/db.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
$db_config = [
|
||||
'host' => 'localhost',
|
||||
'user' => 'root',
|
||||
'pass' => '',
|
||||
'db' => 'test',
|
||||
];
|
||||
|
||||
$dsn = "mysql:host={$db_config['host']};dbname={$db_config['db']};charset=utf8mb4";
|
||||
$opt = [
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
// PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
];
|
||||
|
||||
$db = new PDO($dsn, $db_config['user'], $db_config['pass'], $opt);
|
||||
125
incs/functions.php
Normal file
125
incs/functions.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
function dump($data): void
|
||||
{
|
||||
echo '<pre>' . print_r($data, 1) . '</pre>';
|
||||
}
|
||||
|
||||
function dd($data): never
|
||||
{
|
||||
dump($data);
|
||||
die;
|
||||
}
|
||||
|
||||
function load(array $fillable, $post = true): array
|
||||
{
|
||||
$load_data = $post ? $_POST : $_GET;
|
||||
$data = [];
|
||||
foreach ($fillable as $value) {
|
||||
if (isset($load_data[$value])) {
|
||||
$data[$value] = trim($load_data[$value]);
|
||||
} else {
|
||||
$data[$value] = '';
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
function check_required_fields(array $data): true|array
|
||||
{
|
||||
$errors = [];
|
||||
foreach ($data as $k => $v) {
|
||||
if (empty($v)) {
|
||||
$errors[] = "Не заполнено поле {$k}";
|
||||
}
|
||||
}
|
||||
if (!$errors) {
|
||||
return true;
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
function h(string $s): string
|
||||
{
|
||||
return htmlspecialchars($s, ENT_QUOTES);
|
||||
}
|
||||
|
||||
function old(string $name, $post = true): string
|
||||
{
|
||||
$load_data = $post ? $_POST : $_GET;
|
||||
return isset($load_data[$name]) ? h($load_data[$name]) : '';
|
||||
}
|
||||
|
||||
function redirect(string $url)
|
||||
{
|
||||
header("Location: {$url}");
|
||||
die;
|
||||
}
|
||||
|
||||
function get_errors(array $errors): string
|
||||
{
|
||||
$html = '<ul class="list-unstyled">';
|
||||
foreach ($errors as $error) {
|
||||
$html .= "<li>{$error}</li>";
|
||||
}
|
||||
$html .= '<ul>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
function get_alerts(): void
|
||||
{
|
||||
if (!empty($_SESSION['errors'])) {
|
||||
require VIEWS . '/incs/alert_danger.tpl.php';
|
||||
unset($_SESSION['errors']);
|
||||
}
|
||||
if (!empty($_SESSION['success'])) {
|
||||
require VIEWS . '/incs/alert_success.tpl.php';
|
||||
unset($_SESSION['success']);
|
||||
}
|
||||
}
|
||||
|
||||
function register(array $data): bool
|
||||
{
|
||||
global $db;
|
||||
$stmt = $db->prepare("SELECT COUNT(*) FROM users WHERE email = ?");
|
||||
$stmt->execute([$data['email']]);
|
||||
if ($stmt->fetchColumn()) {
|
||||
$_SESSION['errors'] = 'This email is already taken';
|
||||
return false;
|
||||
}
|
||||
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
$stmt = $db->prepare("INSERT INTO users (name, email, password) VALUES (:name, :email, :password)");
|
||||
$stmt->execute($data);
|
||||
$_SESSION['success'] = 'You have successfully registered';
|
||||
return true;
|
||||
}
|
||||
|
||||
function login(array $data): bool
|
||||
{
|
||||
global $db;
|
||||
$stmt = $db->prepare("SELECT * FROM users WHERE email = ?");
|
||||
$stmt->execute([$data['email']]);
|
||||
if ($row = $stmt->fetch()) {
|
||||
if (!password_verify($data['password'], $row['password'])) {
|
||||
$_SESSION['errors'] = 'Wrong email or password';
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$_SESSION['errors'] = 'Wrong email or password';
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($row as $key => $value) {
|
||||
if ($key != 'password') {
|
||||
$_SESSION['user'][$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$_SESSION['success'] = 'You have successfully logged';
|
||||
return true;
|
||||
}
|
||||
|
||||
function check_auth(): bool
|
||||
{
|
||||
return isset($_SESSION['user']);
|
||||
}
|
||||
10
index.php
Normal file
10
index.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
session_start();
|
||||
require_once __DIR__ . '/incs/config.php';
|
||||
require_once ROOT . '/incs/db.php';
|
||||
require_once ROOT . '/incs/functions.php';
|
||||
|
||||
$title = 'Home';
|
||||
|
||||
require_once VIEWS . '/index.tpl.php';
|
||||
25
login.php
Normal file
25
login.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
session_start();
|
||||
require_once __DIR__ . '/incs/config.php';
|
||||
require_once ROOT . '/incs/db.php';
|
||||
require_once ROOT . '/incs/functions.php';
|
||||
|
||||
if (check_auth()) {
|
||||
redirect('secret.php');
|
||||
}
|
||||
|
||||
$title = 'Login';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$data = load(['email', 'password']);
|
||||
if (true === ($validate = check_required_fields($data))) {
|
||||
if (login($data)) {
|
||||
redirect('secret.php');
|
||||
}
|
||||
} else {
|
||||
$_SESSION['errors'] = get_errors($validate);
|
||||
}
|
||||
}
|
||||
|
||||
require_once VIEWS . '/login.tpl.php';
|
||||
25
register.php
Normal file
25
register.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
session_start();
|
||||
require_once __DIR__ . '/incs/config.php';
|
||||
require_once ROOT . '/incs/db.php';
|
||||
require_once ROOT . '/incs/functions.php';
|
||||
|
||||
if (check_auth()) {
|
||||
redirect('secret.php');
|
||||
}
|
||||
|
||||
$title = 'Register';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$data = load(['name', 'email', 'password']);
|
||||
if (true === ($validate = check_required_fields($data))) {
|
||||
if (register($data)) {
|
||||
redirect('login.php');
|
||||
}
|
||||
} else {
|
||||
$_SESSION['errors'] = get_errors($validate);
|
||||
}
|
||||
}
|
||||
|
||||
require_once VIEWS . '/register.tpl.php';
|
||||
14
secret.php
Normal file
14
secret.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
session_start();
|
||||
require_once __DIR__ . '/incs/config.php';
|
||||
require_once ROOT . '/incs/db.php';
|
||||
require_once ROOT . '/incs/functions.php';
|
||||
|
||||
if (!check_auth()) {
|
||||
redirect('login.php');
|
||||
}
|
||||
|
||||
$title = 'Secret';
|
||||
|
||||
require_once VIEWS . '/secret.tpl.php';
|
||||
71
test.sql
Normal file
71
test.sql
Normal file
@ -0,0 +1,71 @@
|
||||
-- phpMyAdmin SQL Dump
|
||||
-- version 5.2.1
|
||||
-- https://www.phpmyadmin.net/
|
||||
--
|
||||
-- Хост: 127.0.0.1
|
||||
-- Время создания: Сен 16 2023 г., 13:48
|
||||
-- Версия сервера: 10.4.28-MariaDB
|
||||
-- Версия PHP: 8.2.4
|
||||
|
||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
START TRANSACTION;
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
|
||||
--
|
||||
-- База данных: `test`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Структура таблицы `users`
|
||||
--
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`name` varchar(50) NOT NULL,
|
||||
`email` varchar(50) NOT NULL,
|
||||
`password` varchar(255) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
--
|
||||
-- Дамп данных таблицы `users`
|
||||
--
|
||||
|
||||
INSERT INTO `users` (`id`, `name`, `email`, `password`) VALUES
|
||||
(1, 'Nayda Lee', 'zymozynej@mailinator.com', '$2y$10$qJGourjJpP2PjdFyMH3cL.ozfVBPdSXrXqlQajMqQHZaXlRClbGGa'),
|
||||
(2, 'Vaughan Merritt', 'zymozynej2@mailinator.com', '$2y$10$Gpimyv9FAcmhxBXaL9MUZ.QKTOwsX6OvsB2JNUgWLcXWR/hKlLjJq'),
|
||||
(3, 'Mason Wagner', 'bonexasopu@mailinator.com', '$2y$10$tk4Q2wZ014YmdnQyaapfa.ZDPIcgmHh8sZgA/nzcFXcxJXpoEYDMS'),
|
||||
(4, 'User 1', 'user1@mail.com', '$2y$10$IVg4WUIlLn7hH/K1nQk10eBFSjVJjf1prYCHqNHJIt236iZ8vttHO');
|
||||
|
||||
--
|
||||
-- Индексы сохранённых таблиц
|
||||
--
|
||||
|
||||
--
|
||||
-- Индексы таблицы `users`
|
||||
--
|
||||
ALTER TABLE `users`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `email` (`email`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT для сохранённых таблиц
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT для таблицы `users`
|
||||
--
|
||||
ALTER TABLE `users`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
|
||||
COMMIT;
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
7
views/incs/alert_danger.tpl.php
Normal file
7
views/incs/alert_danger.tpl.php
Normal file
@ -0,0 +1,7 @@
|
||||
<div class="container my-2">
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
<?= $_SESSION['errors'] ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
7
views/incs/alert_success.tpl.php
Normal file
7
views/incs/alert_success.tpl.php
Normal file
@ -0,0 +1,7 @@
|
||||
<div class="container my-2">
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
<?= $_SESSION['success'] ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
3
views/incs/footer.tpl.php
Normal file
3
views/incs/footer.tpl.php
Normal file
@ -0,0 +1,3 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
51
views/incs/header.tpl.php
Normal file
51
views/incs/header.tpl.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
if (isset($_GET['do']) && $_GET['do'] == 'exit') {
|
||||
unset($_SESSION['user']);
|
||||
redirect('login.php');
|
||||
}
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title><?= $title ?? 'TITLE' ?></title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg bg-dark border-bottom border-body" data-bs-theme="dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="index.php">Home</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="secret.php">Secret</a>
|
||||
</li>
|
||||
<?php if (check_auth()): ?>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
Hello, <?= $_SESSION['user']['name'] ?>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><a class="dropdown-item" href="?do=exit">Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="register.php">Register</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="login.php">Login</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<?php get_alerts(); ?>
|
||||
9
views/index.tpl.php
Normal file
9
views/index.tpl.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php require_once VIEWS . '/incs/header.tpl.php'; ?>
|
||||
|
||||
<div class="container mt-3">
|
||||
|
||||
<h1><?= $title ?></h1>
|
||||
|
||||
</div>
|
||||
|
||||
<?php require_once VIEWS . '/incs/footer.tpl.php'; ?>
|
||||
29
views/login.tpl.php
Normal file
29
views/login.tpl.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php require_once VIEWS . '/incs/header.tpl.php'; ?>
|
||||
|
||||
<div class="container mt-3">
|
||||
<div class="row">
|
||||
<div class="col-md-6 offset-md-3">
|
||||
<h1><?= $title ?></h1>
|
||||
|
||||
<form method="post">
|
||||
|
||||
<div class="form-floating mb-3">
|
||||
<input name="email" type="email" class="form-control" id="email" placeholder="Email">
|
||||
<label for="email">Email</label>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mb-3">
|
||||
<input name="password" type="password" class="form-control" id="password"
|
||||
placeholder="Password">
|
||||
<label for="password">Password</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Login</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once VIEWS . '/incs/footer.tpl.php'; ?>
|
||||
34
views/register.tpl.php
Normal file
34
views/register.tpl.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php require_once VIEWS . '/incs/header.tpl.php'; ?>
|
||||
|
||||
<div class="container mt-3">
|
||||
<div class="row">
|
||||
<div class="col-md-6 offset-md-3">
|
||||
|
||||
<h1><?= $title?></h1>
|
||||
|
||||
<form method="post">
|
||||
|
||||
<div class="form-floating mb-3">
|
||||
<input name="name" type="text" class="form-control" id="name" placeholder="Name" value="<?= old('name') ?>">
|
||||
<label for="name">Name</label>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mb-3">
|
||||
<input name="email" type="email" class="form-control" id="email" placeholder="Email" value="<?= old('email') ?>">
|
||||
<label for="email">Email</label>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mb-3">
|
||||
<input name="password" type="password" class="form-control" id="password" placeholder="Password">
|
||||
<label for="password">Password</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Register</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once VIEWS . '/incs/footer.tpl.php'; ?>
|
||||
9
views/secret.tpl.php
Normal file
9
views/secret.tpl.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php require_once VIEWS . '/incs/header.tpl.php'; ?>
|
||||
|
||||
<div class="container mt-3">
|
||||
|
||||
<h1><?= $title ?></h1>
|
||||
|
||||
</div>
|
||||
|
||||
<?php require_once VIEWS . '/incs/footer.tpl.php'; ?>
|
||||
Reference in New Issue
Block a user