Gestion de session solide

Beaucoup de gestions de sessions en php me semblent mal faites et dangereuses. Voici un exemple de gestion de session créé par mes soins et qui me semble bien plus sûre (Si vous voyez des failles, n'hésitez pas à m'en faire part). Buts: Simplicité, solidité.

Dans cet exemple, le login/mot de passe est codé en dur (toto/titi). A vous d'adapter pour taper dans LDAP, une base mySQL ou autre.

Caractéristiques:

Améliorations possibles:

La page de login:

login.php
<?php 
include 'session.inc';
if (isset($_POST['login']) && isset($_POST['password']) && (check_auth($_POST['login'], $_POST['password'])))
{
	header('Location: index.php');
}
?>
<html>
<head><title>Login</title></head>
<body>
<form method="post" action="login.php">
Please login:<br>
        Login : <input type="text" name="login"> <br>
        Password : <input type="password" name="password">
        <input type="submit" value="Login">
</form>
</body>
</html>

La page de logout:

logout.php
<?php include 'session.inc'; logout(); ?>

Une page-type accessible uniquement si l'utilisateur est logué:

index.php
<?php include 'session.inc'; check_login(); ?>
<html>
<head><title>Index</title></head>
<body>
Hello <?php print $_SESSION['username']; ?>, you are logged in.<br>
<a href="logout.php">Logout</a>
</body>
</html>

Et enfin la gestion de session elle-même:

session.inc
<?php
/* session.inc 
Session management.
 
Instructions: Each page must include: include 'session.inc'; check_login();
 
Features:
- If the user is not authenticated, he/she will be automatically redirected to login page.
- Everything is stored on server-side (we do not trust client-side data, such as cookie expiration)
- IP addresses are checked on each access to prevent session cookie hijacking (such as Firesheep)
- Session expires on user inactivity (Session expiration date is automatically updated everytime the user accesses a page.)
- A unique secret key is generated on server-side for this session (and never sent over the wire) which can be used
  to sign forms (HMAC) or generate form tokens (to prevent XSRF attacks). (See $_SESSION['uid'] )
 
*/
 
define('INACTIVITY_TIMEOUT',3600); // (in seconds). If the user does not access any page within this time, his/her session is considered expired.
 
ini_set('session.use_cookies', 1);       // Use cookies to store session.
ini_set('session.use_only_cookies', 1);  // Force cookies for session (phpsessionID forbidden in URL)
ini_set('session.use_trans_sid', false); // Prevent php to use sessionID in URL if cookies are disabled.
 
session_start();
 
function allIPs()
// Returns the IP address of the client (Used to prevent session cookie hijacking.)
{
    $ip = $_SERVER["REMOTE_ADDR"];
    // Then we use more HTTP headers to prevent session hijacking from users behind the same proxy.
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip=$ip.'_'.$_SERVER['HTTP_X_FORWARDED_FOR']; }
    if (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip=$ip.'_'.$_SERVER['HTTP_CLIENT_IP']; }
    return $ip;
}
 
function check_auth($login,$password) 
// Check that user/password is correct.
{
    if ($login=="toto" && $password=="titi")
    {
        $_SESSION['uid'] = sha1(uniqid('',true).'_'.mt_rand()); // generate unique random number (different than phpsessionid)
                                                                // which can be used to hmac forms and form token (to prevent XSRF)
        $_SESSION['ip']=allIPs();                // We store IP address(es) of the client to make sure session is not hijacked.
        $_SESSION['username']=$login;
        $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT;  // Set session expiration.
        return True;
    }
    else
    {
        return False;
    }
}
 
function check_login()
// Make sure user is logged in. Redirect to login page if not.
{
    // If session does not exist on server side, or IP address has changed, or session has expired, show login screen.
    if (!isset ($_SESSION['uid']) || !$_SESSION['uid'] || $_SESSION['ip']!=allIPs() || time()>=$_SESSION['expires_on'])
    {
        logout();
    }
    $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT;  // User accessed a page : Update his/her session expiration date.
}
 
function logout()
// Force logout, redirect to login page.
{
    unset($_SESSION['uid'],$_SESSION['ip'],$_SESSION['expires_on']);   // Delete server-side session info
    header('Location: login.php');
    exit();
    // We do not bother deleting the phpsessionID cookie, because it can't be used anyway (All server-side
    // data attached to this session cookie is deleted. This makes the cookie useless. )
}
 
?>

Si vous avez des remarques, idées, critiques: