In questo articolo vedremo un esempio pratico per gestire il Login/Logout di un utente. L'esempio è puramente didattico. Per un approccio "professionale e sicuro" al problema si consigli di utilizzare un framework PHP titpo CodeIgniter o similare (vedi articolo su CodeIgniter).
Useremo gli esempi Bootstrap 4 per i template e NetBeans IDE per lo sviluppo (demo).
Cosa ci serve:
* XAMPP
* NetBeans IDE
* Database con tabella utenti (users) popolata (almeno 2-3 record)con PW crittografata MD5
* phpMyAdmin per ispezionare DB e tabella (nomi campi e dati)
* Dati di accesso al database (per MySQL su XAMPP in locale):
- host=localhost
- username=root
- password="" (vuota!)
- nome DB=esempio2 (nel mio caso)
Link per progetto:
(1) Boostrap 4 Home Page-Login-Dashboard: https://getbootstrap.com/docs/4.0/examples/
(2) PHP MySQL Database: https://www.w3schools.com/php/php_mysql_intro.asp
(3) PHP Sessioni: https://www.w3schools.com/php/php_sessions.asp
(1) Risorse utilizzate del file: bootstrap-4.0.0.zip
* cartelle: dist e assets (complete)
* cartelle: sticky-footer-navbar; sign-in; dashboard; presenti in bootstrap-4.0.0\docs\4.0\examples
(2): PHP MySQL Select Data-->HTML table:Example (MySQLi Object-oriented)-->2 esempio Object-oriented
(3) Destroy a PHP Session
Procediamo
Preparazione dei template Bootstrap 4
- Lanciamo XAMPP ed attiviamo Apache e MySQL
- Lanciamo NetBeans IDE e creiamo un nuovo progetto PHP (nell'esempio: ClaudioShop)
- Scarichiamo e scompattiamo gli esempi Bootstrap 4 (link 1)
- Copiamo le cartelle dist e assets nella root del nostro progetto
- Andiamo in bootstrap-4.0.0\docs\4.0\examples
- Entriamo nella cartella: sticky-footer-navbar e copiamo il file sticky-footer-navbar.css nella root del nostro progetto
- Eseguire (doppio click) il file index.html per vedere come si presenta il template
- Apriamo con un editor di testo il file index.html e copiamone il contenuto nell'index.php del nostro progetto (la nostra Home Page)
- Modifichiamo nel file index.php i percorsi di caricamento delle librerie in accordo al nostro progetto (togliere tutti i ../../../ ecc.) e verificare che la pagina si veda correttamente
- Andare nella cartella Sign-in di Boostrap4 examples
- Creare una nuova pagina di nome login.php ed incollarci dentro il contenuto del file index.html della cartella e copiare il file signin.css nella root. Modificare il codice per il caricamento corretto delle librerie e verificare che la pagina si veda correttamente
- Andare nella cartella Dashboard di Bootstrap examples
- Creare una nuova pagina dashboard.php ed incollarci dentro il contenuto del file index.html e copiare il relativo css nella root del progetto. Modificare il codice per il caricamento delle librerie e verificare che la pagina si veda correttamente
- Modificare una voce di menu di index.php in modo che punti a login.php (<a class="nav-link" href='login.php'>Login</a>)
- Modificare il file login.php aggiungendo: method="post" action="login.php" al tag FORM e gli attributi name="email" e name="password" ai rispettivi tag INPUT
Creazione o Importazione del database
- Aprire il browser e digitare localhost. Quindi dal menu di XAMPP avviare phpMyAdmin.
- Creare un nuovo database (esempio2 nel tutorial) ed una nuova tabella (utenti nel tutorial) con almeno due campi: username e password
- Inserire almeno un record (la password deve essere crittografata con MD5)
- In alternativa scaricare il file esempio2.sql del tutorial ed importarlo con phpMyAdmin (se non sai come fare vedi il mio tutorial su YouTube)
Scriviamo il codice PHP per il login/logout
Posizioniamoci all'inizio del file login.php e copiamo e incolliamo il codice prelevato dal link 2 quindi effettuare le seguenti modifiche:
<?php
$msg=""; //Gestione messaggio d'errore
if (isset($_POST['email']) && isset($_POST['password'])) {
//Recupero dati dal form
$user = $_POST['email'];
$pw = $_POST['password'];
$pw_md5= md5($pw);
//Accesso al database
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "esempio2";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT * FROM utenti WHERE username='$user' AND password='$pw_md5'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// Attivo la sessione
session_start();
$_SESSION['datiUtente']=$result->fetch_assoc();
$_SESSION['login']=TRUE;
header("location: dashboard.php");
} else {
//echo "0 results";
$msg="Nome utente o password errati";
}
$conn->close();
}
?>
Proviamo se funziona il login!
Inseriamo prima delle credenziali errate e vediamo che cosa risponde il sistema. Dopo proviamo ad inserire le credenziali corrette (se avete utilizzato il database del tutorial)
Username: Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.
Password: mario
Se tutto funziona dovremmo essere indirizzati alla pagina Dashboard (file dashboard.php).
Si può anche verificare se è stata creato il cookie di sessione: da Chrome premere F12, selezionare la scheda Application; Dovreste trovare un cookie di nome PHPSESSID. Se c'è vuol dire che la sessione è stata creata!
Scriviamo il codice PHP per il logout
Creiamo un nuovo file di nome logout.php e copiamoci dentro il codice prelevato al link 3 ed aggiungiamo il comando di re-indirizzamento: header("location: index.php");
<?php
// remove all session variables
session_unset();
// destroy the session
session_destroy();
//Reindirizza alla home page
header("location: index.php");
?>
Proteggiamo la Dashboard da accessi non autorizzati ed attiviamo il link per il logout
Posizioniamoci all'inizio del file dashboard.php ed aggiungiamo le seguenti righe di codice PHP:
<?php
session_start();
if(!isset($_SESSION['login']))header("location: login.php"); //Accesso riservato agli uteti autenticati
?>
Se la variabile di sessione non esiste (quindi l'utente non è loggato!) si viene re-indirizzati alla pagina di login
Modifichiamo la riga del link "Sign Out" così: <a class="nav-link" href='logout.php'>Sign out</a>
Ricaricate la pagina e verificate che il tutto funzioni. Provate un ciclo completo:
Home page-->Login-->Dashboard-->Home Page
Bene il nostro tutorial finisce qui.
Guarda il video tutorial
Il codice del tutorial
il file index.php
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href='favicon.ico'>
<title>ClaudioShop|Home</title>
<!-- Bootstrap core CSS -->
<link href='dist/css/bootstrap.min.css' rel="stylesheet">
<!-- Custom styles for this template -->
<link href='sticky-footer-navbar.css' rel="stylesheet">
</head>
<body>
<header>
<!-- Fixed navbar -->
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
<a class="navbar-brand" href="#">Fixed navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href='login.php'>Login</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
</ul>
<form class="form-inline mt-2 mt-md-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
</header>
<!-- Begin page content -->
<main role="main" class="container">
<h1 class="mt-5">Benvenuti da Claudio Shop E-Commerce</h1>
<p class="lead">Pin a fixed-height footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS. A fixed navbar has been added with <code>padding-top: 60px;</code> on the <code>body > .container</code>.</p>
<p>Back to <a href="/jm/../sticky-footer">the default sticky footer</a> minus the navbar.</p>
</main>
<footer class="footer">
<div class="container">
<span class="text-muted">Realizzato da Vincent</span>
</div>
</footer>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="/jm/assets/js/vendor/jquery-slim.min.js"><\/script>')</script>
<script src='assets/js/vendor/popper.min.js'></script>
<script src='dist/js/bootstrap.min.js'></script>
</body>
</html>
Il file login.php
<?php
$msg=""; //Gestione messaggio d'errore
if (isset($_POST['email']) && isset($_POST['password'])) {
//Recupero dati dal form
$user = $_POST['email'];
$pw = $_POST['password'];
$pw_md5= md5($pw);
//Accesso al database
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "esempio2";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT * FROM utenti WHERE username='$user' AND password='$pw_md5'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// Attivo la sessione
session_start();
$_SESSION['datiUtente']=$result->fetch_assoc();
$_SESSION['login']=TRUE;
header("location: dashboard.php");
} else {
//echo "0 results";
$msg="Nome utente o password errati";
}
$conn->close();
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href='favicon.ico'>
<title>Signin Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href='dist/css/bootstrap.min.css' rel="stylesheet">
<!-- Custom styles for this template -->
<link href='signin.css' rel="stylesheet">
</head>
<body class="text-center">
<form class="form-signin" method="post" action="login.php">
<img class="mb-4" src="https://getbootstrap.com/assets/brand/bootstrap-solid.svg" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="inputEmail" class="sr-only">Email address</label>
<input type="email" name="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required>
<div class="checkbox mb-3">
<label>
<?php print $msg; ?>
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
</form>
</body>
</html>
Il file dashboard.php
<?php
session_start();
if(!isset($_SESSION['login']))header("location: login.php"); //Accesso riservato agli uteti autenticati
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href='favicon.ico'>
<title>Dashboard Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href='dist/css/bootstrap.min.css' rel="stylesheet">
<!-- Custom styles for this template -->
<link href='dashboard.css' rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="#">Company name</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" href='logout.php'>Sign out</a>
</li>
</ul>
</nav>
<div class="container-fluid">
<div class="row">
<nav class="col-md-2 d-none d-md-block bg-light sidebar">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" href="#">
<span data-feather="home"></span>
Dashboard <span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="file"></span>
Orders
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="shopping-cart"></span>
Products
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="users"></span>
Customers
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="bar-chart-2"></span>
Reports
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="layers"></span>
Integrations
</a>
</li>
</ul>
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>Saved reports</span>
<a class="d-flex align-items-center text-muted" href="#">
<span data-feather="plus-circle"></span>
</a>
</h6>
<ul class="nav flex-column mb-2">
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="file-text"></span>
Current month
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="file-text"></span>
Last quarter
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="file-text"></span>
Social engagement
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="file-text"></span>
Year-end sale
</a>
</li>
</ul>
</div>
</nav>
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom">
<h1 class="h2">Dashboard</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group mr-2">
<button class="btn btn-sm btn-outline-secondary">Share</button>
<button class="btn btn-sm btn-outline-secondary">Export</button>
</div>
<button class="btn btn-sm btn-outline-secondary dropdown-toggle">
<span data-feather="calendar"></span>
This week
</button>
</div>
</div>
<canvas class="my-4" id="myChart" width="900" height="380"></canvas>
<h2>Section title</h2>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>#</th>
<th>Header</th>
<th>Header</th>
<th>Header</th>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>1,001</td>
<td>Lorem</td>
<td>ipsum</td>
<td>dolor</td>
<td>sit</td>
</tr>
<tr>
<td>1,002</td>
<td>amet</td>
<td>consectetur</td>
<td>adipiscing</td>
<td>elit</td>
</tr>
<tr>
<td>1,003</td>
<td>Integer</td>
<td>nec</td>
<td>odio</td>
<td>Praesent</td>
</tr>
<tr>
<td>1,003</td>
<td>libero</td>
<td>Sed</td>
<td>cursus</td>
<td>ante</td>
</tr>
<tr>
<td>1,004</td>
<td>dapibus</td>
<td>diam</td>
<td>Sed</td>
<td>nisi</td>
</tr>
<tr>
<td>1,005</td>
<td>Nulla</td>
<td>quis</td>
<td>sem</td>
<td>at</td>
</tr>
<tr>
<td>1,006</td>
<td>nibh</td>
<td>elementum</td>
<td>imperdiet</td>
<td>Duis</td>
</tr>
<tr>
<td>1,007</td>
<td>sagittis</td>
<td>ipsum</td>
<td>Praesent</td>
<td>mauris</td>
</tr>
<tr>
<td>1,008</td>
<td>Fusce</td>
<td>nec</td>
<td>tellus</td>
<td>sed</td>
</tr>
<tr>
<td>1,009</td>
<td>augue</td>
<td>semper</td>
<td>porta</td>
<td>Mauris</td>
</tr>
<tr>
<td>1,010</td>
<td>massa</td>
<td>Vestibulum</td>
<td>lacinia</td>
<td>arcu</td>
</tr>
<tr>
<td>1,011</td>
<td>eget</td>
<td>nulla</td>
<td>Class</td>
<td>aptent</td>
</tr>
<tr>
<td>1,012</td>
<td>taciti</td>
<td>sociosqu</td>
<td>ad</td>
<td>litora</td>
</tr>
<tr>
<td>1,013</td>
<td>torquent</td>
<td>per</td>
<td>conubia</td>
<td>nostra</td>
</tr>
<tr>
<td>1,014</td>
<td>per</td>
<td>inceptos</td>
<td>himenaeos</td>
<td>Curabitur</td>
</tr>
<tr>
<td>1,015</td>
<td>sodales</td>
<td>ligula</td>
<td>in</td>
<td>libero</td>
</tr>
</tbody>
</table>
</div>
</main>
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="/jm/../../../../assets/js/vendor/jquery-slim.min.js"><\/script>')</script>
<script src='assets/js/vendor/popper.min.js'></script>
<script src='dist/js/bootstrap.min.js'></script>
<!-- Icons -->
<script src="https://unpkg.com/feather-icons/dist/feather.min.js"></script>
<script>
feather.replace()
</script>
<!-- Graphs -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
datasets: [{
data: [15339, 21345, 18483, 24003, 23489, 24092, 12034],
lineTension: 0,
backgroundColor: 'transparent',
borderColor: '#007bff',
borderWidth: 4,
pointBackgroundColor: '#007bff'
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
},
legend: {
display: false,
}
}
});
</script>
</body>
</html>
Il file esempio2.sql
-- phpMyAdmin SQL Dump -- version 4.7.4 -- https://www.phpmyadmin.net/ -- -- Host: 127.0.0.1 -- Creato il: Mag 23, 2020 alle 11:40 -- Versione del server: 10.1.30-MariaDB -- Versione PHP: 7.2.1 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET AUTOCOMMIT = 0; 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 */; -- -- Database: `esempio2` -- CREATE DATABASE IF NOT EXISTS `esempio2` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; USE `esempio2`; -- -------------------------------------------------------- -- -- Struttura della tabella `utenti` -- CREATE TABLE `utenti` ( `id` int(11) NOT NULL, `nome` varchar(60) NOT NULL, `cognome` varchar(50) NOT NULL, `username` varchar(100) NOT NULL, `password` varchar(128) NOT NULL, `data_registrazione` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Dump dei dati per la tabella `utenti` -- INSERT INTO `utenti` (`id`, `nome`, `cognome`, `username`, `password`, `data_registrazione`) VALUES (1, 'Mario', 'Rossi', Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.', 'de2f15d014d40b93578d255e6221fd60', '2020-04-03 13:46:30'), (2, 'Eva', 'Kant', Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.', '14bd76e02198410c078ab65227ea0794', '2020-04-03 13:46:30'); -- -- Indici per le tabelle scaricate -- -- -- Indici per le tabelle `utenti` -- ALTER TABLE `utenti` ADD PRIMARY KEY (`id`); -- -- AUTO_INCREMENT per le tabelle scaricate -- -- -- AUTO_INCREMENT per la tabella `utenti` -- ALTER TABLE `utenti` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; 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 */;
Allegati Articolo
* Database
* Il progetto completo realizzato con NetBeans IDE
* Demo