Allora, questa è la mia opinione in merito alla questione Login Sicuro. E' solo la mia personale (e nemmeno troppo elevata) esperienza e quello che mi fa pensare, nulla di più. Se avete un'opinione diversa siete liberi di cazziarmi, ma vorrei il motivo preciso, non un "Stai dicendo una manica di #####" e basta.
Intro
IMHO, devi un po' vedere il "livello" di sicurezza e di accesso che è necessario. Mi spiego meglio, potrebbero semplicemente volere una pagina per l'inserimento di news che però sia accessibile da più persone, anche con la stessa password (che in termini di security è uguale a 0), tuttavia, se si tratta si un azienda con due o tre persone che devono accedere, non credo che valga la pena di creare un intero sistema di autenticazione con controlli se un utente è già loggato o meno.
Allo stesso tempo, se invece le pagina effettua delle operazioni delicate e c'è la necessità di sapere chi fa cosa, e di avere, quindi, un capro espiatorio in caso di disastro, un sistema completo di accesso esclusivo è necessario.
Bisogna, prima di tutto vedere a cosa ti serve, dato che anche il tuo sistema è validissimo, per casi che non richiedono sicurezza elevata.
Login Base
Come login di Base, quello che hai scritto tu va benissimo. Quello che manca, anche se suppongo (e spero) tu faccia già, è un controllo per prevenire SQL Injection, che, anche se è un controllo base, è un passo necessario.
Un esempio su come prevenire SQL Injection:
Codice PHP:
$username = str_replace("'", "", $_POST['username']); //Questo ovviamente presuppone che non ci siano nomi utente tipo "Giuseppe d'Arrigo"
$password = SHA1($_POST['password']);
$query = "SELECT * FROM Utente WHERE username LIKE '$username' AND password LIKE '$password'";
...
Login Esclusivo
Il login esclusivo, necessita di implementare un modo per controllare se l'utente è già autenticato. Questo si fa facilmente, inserendo un campo Logged VARCHAR(16) DEFAULT NULL nella tabella Utente, al momento del login, dopo aver ottenuto i dati dell'utente con una query tipo quella sopra, si controllerà che Logged == NULL, in caso positivo, si aggiorna la tabella con Logged = IP_del_Client, altrimenti si fa prensente che l'utente è già autenticato presso il sistema (così uno può accorgersi se gli hanno bucato l'account).
A questo punto, si può decidere se far sloggare l'utente precedente e far loggare quello nuovo, oppure se bloccare il secondo, lasciando il primo loggato. Questo dipende dal tipo di sistema, per esempio in un azienda dove uno può accedere da più di un PC, potrebbe far comodo un sistema di logout del primo utente (per dire, uno chiude il browser da una parte senza fare logout, poi fa login da un'altra parte). Allo stesso tempo, in un servizio di intranet può essere più comodo controllare anche gli accessi.
Il secondo punto da controllare e la session expire che, essendo gestita dal DB, deve avere una data di scadenza.
Per questo si utilizza un campo Expire TIMESTAMP DAFAULT NULL. Quando l'utente richiede una pagina Privata il campo Expire verrà aggiornato a NOW() + durata della session. Inoltre, nel momento del login si controllerà se l'utente è autenticato (Logged != NULL) e se Expire > NOW(), se uno di questi controlli fallisce allora l'utente può accedere.
In sostanza (metti che il codice sia successivo a quello soprapostato):
Codice PHP:
$result = mysql_query($query, $db);
$user = mysql_fetch_assoc($result);
if(!$user)
{
echo "Nome utente o Password errati";
}
else
{
if($user['Logged'] != null)
{
$ip = get_IP(); //Questa non è una funzione standard, ma una funzione che, metti, ho scritto per ottenere l'IP del client che effettua la richiesta dal suo USER-AGENT o dall'header della richiesta.
if($user['Logged'] == $ip)
{
//L'utente era già autenticato da questo client, probabilmente è scaduta la sessione del Web Server e l'utente si è dovuto riautenticare
//Rimetti i dati dell'utente in sessione ed aggiorna il campo Expire a NOW()
}
else
{
//L'utente non era autenticato su questa macchina
if($user['Expire'] < mktime())
{
//La sessione precedente è scaduta, l'utente può autenticarsi
//Metti i dati dell'utente in sessione ed aggiorna Expire a NOW e Logged a $ip
}
else
{
//La sessione è ancora in uso da un altro utente
//A seconda di quello che scegli, bloccalo o aggiorna il DB con i nuovi dati
}
}
}
else
{
//Non c'era utente autenticato
//Metti i dati dell'utente in sessione ed aggiorna il DB
}
}
In Ultimus
In ultimo, devo quotare carlo2002, inserisci SSL nel tuo sito, per criptare la connessione. Magari, non ti interesserà di criptare tutto il sito, ma solo la pagina di LOGIN in modo che i dati vengano trasmessi in maniera sicura.
Codice PHP:
<form action="https://www.tuosito.it/scripts/actor.login.php" method="POST">
Username : <input type="text" name="username" />
</p>
Password : <input type="password" name="password" />
</p>
<input type="submit" value="Accedi" />
</p>
</form>
Alla fine di actor.login.php ci sarà:
Codice PHP:
header("Location: [url]http://www.tuosito.it/index.php[/url]");
exit;