« Ritorna al blog

Ritorna alla lista completa degli articoli

Mettiti alla prova: utilizzo delle session e autenticazione

PHP - SFIDE - febbraio 11, 2022

In 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:

  1. home_page.php
  2. accedi.php
  3. logout.php
  4. accedi.css
  5. index.css
  6. 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 &copy; 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">&copy; 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:

  1. gli account vanno letti da un file di testo;
  2. la funzione deve restituire true in caso di successo e false in caso di errore o insuccesso;
  3. 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">&copy; 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>
Mettiti alla prova: utilizzo delle session e autenticazione
Mettiti alla prova: utilizzo delle session e autenticazione
Mettiti alla prova: utilizzo delle session e autenticazione
Mettiti alla prova: utilizzo delle session e autenticazione