« Ritorna al blog
Ritorna alla lista completa degli articoli
Mettiti alla prova: utilizzo delle session e autenticazione
PHP - SFIDE - febbraio 11, 2022In questo esercizio ci concentreremo sull'autenticazione tramite un form. Dovete solo completare la funzione login() contenuta nel file accedi.php per rendere l'applicativo funzionante. In tutto abbiamo 6 file:
- home_page.php
- accedi.php
- logout.php
- accedi.css
- index.css
- password_hash.txt
Il primo file è l'home_page.php dove è presente un menù e un messaggio di benvenuto in caso l'utente si sia loggato. Il file accedi.php contiene il form per autenticarsi e l'ultimo file, logout.php, elimina le informazioni della sessione per disconnettere l'utente. Lo scopo dell'esercizio è riuscire a risolvere la funzione login() contenuta del file accedi.php, leggendo username e password da un file di testo. Il file che contiene gli accounts è stato creato nel precedente esercizio. Se hai già risolto l'esercizio dovresti avere un file simile a questo con almeno quattro accounts:
gianfrancopercopo,$2y$10$dJ8CoFZXh2mBa14k0A3rveX6Nt5i3U0.YXXRNoE8zlujPU6OI5Q4y
mariorossi,$2y$10$EBBdrs3pgAmN6HOa1CEX9uHb1/pm2G/CGec68K4mIxKChVc1Ssp.a
Il file accedi.css e index.css contengono la formattazione degli stili delle rispettive pagine web. Ecco il codice dei file che ci interessano:
index.php
<?php session_start(); ?>
<!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>Home Page</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
<link rel="stylesheet" href="css/index.css">
</head>
<body class="d-flex h-100 text-center text-white bg-dark">
<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
<header class="mb-auto">
<div>
<h3 class="float-md-start mb-0">My site</h3>
<nav class="nav nav-masthead justify-content-center float-md-end">
<a class="nav-link active" aria-current="page" href="#">Home</a>
<?php if (isset($_SESSION["user_log"])) : ?>
<a class="nav-link" href="logout.php">Logout</a>
<?php else : ?>
<a class="nav-link" href="accedi.php">Accedi</a>
<?php endif ?>
</nav>
</div>
</header>
<main class="px-3">
<h1>Home page</h1>
<p class="lead">Esercizio sull'area di login.<br> Dopo esserti loggato dovresti vedere il tuo username e un messaggio di benvenuto.</p>
<p class="lead">
<?php if (isset($_SESSION["user_log"])) : ?>
<h3>Benvenuto <span class="text-info"><?php echo $_SESSION["user_log"]; ?></span></h3>
<hr>
Grazie per esserti loggato al nostro portale.
<?php else : ?>
<a href="accedi.php" class="btn btn-lg btn-secondary fw-bold border-white bg-white">Accedi</a>
<?php endif ?>
</p>
</main>
<footer class="mt-auto text-white-50">
<p>Copyright © 2021</p>
</footer>
</div>
<!-- Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
index.css
html,
body {
height: 100%;
}
.btn-secondary,
.btn-secondary:hover,
.btn-secondary:focus {
color: #333;
text-shadow: none;
}
body {
text-shadow: 0 .05rem .1rem rgba(0, 0, 0, .5);
box-shadow: inset 0 0 5rem rgba(0, 0, 0, .5);
}
.cover-container {
max-width: 42em;
}
.nav-masthead .nav-link {
padding: .25rem 0;
font-weight: 700;
color: rgba(255, 255, 255, .5);
background-color: transparent;
border-bottom: .25rem solid transparent;
}
.nav-masthead .nav-link:hover,
.nav-masthead .nav-link:focus {
border-bottom-color: rgba(255, 255, 255, .25);
}
.nav-masthead .nav-link+.nav-link {
margin-left: 1rem;
}
.nav-masthead .active {
color: #fff;
border-bottom-color: #fff;
}
accedi.php
<?php session_start(); ?>
<!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>Accedi</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
<link rel="stylesheet" href="css/accedi.css">
</head>
<body>
<?php
global $msg;
function login($username, $password)
{
// da completare
return false;
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (isset($_POST["btn_submit"])) {
$username = trim(strtolower($_POST["username"]));
$password = trim($_POST["password"]);
if (login($username, $password) == true) {
header("location:index.php");
exit();
} else {
$msg = '<div class="alert alert-dismissible alert-danger">';
$msg .= '<button type="button" class="btn-close" data-bs-dismiss="alert"></button>';
$msg .= '<strong>Attenzione!</strong> Errore in fase di autenticazione';
$msg .= '</div>';
}
}
}
?>
<main class="form-signin text-center">
<form id="form" name="form" method="POST" action="<?php echo $_SERVER["PHP_SELF"]; ?>">
<i class="logo bi bi-bootstrap-fill"></i>
<h1 class="h3 mb-3 fw-normal">Area riservata</h1>
<?php echo $msg; ?>
<div class="form-floating">
<input type="username" class="form-control" id="username" name="username" placeholder="Username" pattern=".{8,}" title="L'username deve contenere al meno otto caratteri" required>
<label for="username">Username</label>
</div>
<div class="form-floating">
<input type="password" class="form-control" id="password" name="password" placeholder="Password" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" title="La password deve contenere almeno un numero, una lettera maiuscola e minuscola, almeno otto caratteri" required>
<label for="password">Password</label>
</div>
<button type="submit" class="w-100 btn btn-lg btn-primary" name="btn_submit" type="submit">Accedi</button>
<p class="mt-5 mb-3 text-muted">© 2022 - <a href="index.php">Torna alla Home Page</a></p>
</form>
</main>
<!-- Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
accedi.css
html,
body {
height: 100%;
}
body {
display: flex;
align-items: center;
padding-top: 40px;
padding-bottom: 40px;
background-color: #f5f5f5;
}
.logo {
font-size: 57px;
}
.form-signin {
width: 100%;
max-width: 330px;
padding: 15px;
margin: auto;
}
.form-signin .checkbox {
font-weight: 400;
}
.form-signin .form-floating:focus-within {
z-index: 2;
}
.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
logout.php
<?php
session_start();
unset($_SESSION['user_log']);
header("location:index.php");
exit();
?>
Una volta creato i file e verificato che tutto si veda correttamente concentratevi sulla funzione login() contenuta all'interno del file accedi.php.
La funzione deve rispondere alle seguenti richieste:
- gli account vanno letti da un file di testo;
- la funzione deve restituire true in caso di successo e false in caso di errore o insuccesso;
- la funzione deve memorizzare, attraverso l'uso della variabile globale $_SESSION["user_log"], l'username dell'utente;
Una volta scritto il codice necessario dovreste vedere un messaggio di benvenuto nella home page con l'username dell'utente che si è loggato e il pulsante logout, al posto di accedi, per effettuare la disconnessione. Fate gli opportuni test e divertitevi :)
accedi.php
<?php session_start(); ?>
<!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>Accedi</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
<link rel="stylesheet" href="css/accedi.css">
</head>
<body>
<?php
global $msg;
function login($username, $password)
{
// da completare
$accounts = file_get_contents("file/password_hash.txt");
$accounts = explode("\n", $accounts);
foreach ($accounts as $account) {
$account = explode(",", $account);
if ($username == $account[0] && password_verify($password, $account[1])) {
session_regenerate_id();
$_SESSION["user_log"] = $username;
return true;
}
}
return false;
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (isset($_POST["btn_submit"])) {
$username = trim(strtolower($_POST["username"]));
$password = trim($_POST["password"]);
if (login($username, $password) == true) {
header("location:index.php");
exit();
} else {
$msg = '<div class="alert alert-dismissible alert-danger">';
$msg .= '<button type="button" class="btn-close" data-bs-dismiss="alert"></button>';
$msg .= '<strong>Attenzione!</strong> Errore in fase di autenticazione';
$msg .= '</div>';
}
}
}
?>
<main class="form-signin text-center">
<form id="form" name="form" method="POST" action="<?php echo $_SERVER["PHP_SELF"]; ?>">
<i class="logo bi bi-bootstrap-fill"></i>
<h1 class="h3 mb-3 fw-normal">Area riservata</h1>
<?php echo $msg; ?>
<div class="form-floating">
<input type="username" class="form-control" id="username" name="username" placeholder="Username" pattern=".{8,}" title="L'username deve contenere al meno otto caratteri" required>
<label for="username">Username</label>
</div>
<div class="form-floating">
<input type="password" class="form-control" id="password" name="password" placeholder="Password" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" title="La password deve contenere almeno un numero, una lettera maiuscola e minuscola, almeno otto caratteri" required>
<label for="password">Password</label>
</div>
<button type="submit" class="w-100 btn btn-lg btn-primary" name="btn_submit" type="submit">Accedi</button>
<p class="mt-5 mb-3 text-muted">© 2022 - <a href="index.php">Torna alla Home Page</a></p>
</form>
</main>
<!-- Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>