I see a lot of people trying to write code to authenticate users logging into a PHP website. This is some code I cobbled together in december of 2008 and it has worked problem free since then.
// I've already sanitized all GET, POST, and COOKIE data at this point. function check_login() { global $DB; $login_justnow=false; // if the user isn't logged in and they're POSTing a login request, process it if(!get_session('user/id') && isset($_POST['login']) { $name=$_POST['login_name']; $remember_me=isset($_POST['remember_me'])?1:0; $pass=md5($_POST['login_pass']); $user_id=$DB->QueryXY("SELECT id FROM `users` WHERE name='$name' AND pass='$pass' AND confirmed='1' LIMIT 1"); if(isset($user_id)) { account_login($user_id,$remember_me); $login_justnow=true; $name=get_session("user/given_name")?', '.get_session("user/given_name"):''; add_notice("Welcome$name!"); } else { add_error("Login failed."); account_logout(); } } // if the user isn't logged in but has a COOKIE, process it if(!get_session("user/id") && isset($_COOKIE["remember_me"]) ) { list($user_id,$cookie_code)=@unserialize(stripslashes($_COOKIE["remember_me"])); if(isset($user_id) && isset($cookie_code)) { $cookie=md5($cookie_code); $result=$DB->QueryArray("SELECT * FROM `users` WHERE id='$user_id' AND cookie='$cookie' AND confirmed='1' LIMIT 1"); if(count($result)) { account_login($user_id,true); $login_justnow=true; $name=get_session("user/given_name")?', '.get_session("user/given_name"):''; add_notice("Welcome$name!"); } } } // if the user's session says they're logged in, process it if(get_session("user/id") && $login_justnow===false) { $user_id=get_session("user/id"); $cookie=get_session("user/cookie"); $ip=get_session("user/ip"); $session=session_id(); $query="SELECT * FROM `users` WHERE id='$user_id' AND ip='$ip' AND session='$session' AND cookie='$cookie' AND confirmed='1' LIMIT 1"; $result=$DB->DoQuery($query); if($DB->NumRows($result)) { account_login($user_id,false); } else { add_error("Session security failed."); account_logout(); } $DB->EndQuery($result); } // check if the user actually has rights to this part of the site - your implementation may vary } function account_login($user_id,$remember_me) { global $DB; if(user_is_logged_in()) return; // update cookie if($remember_me==true) { $cookie_code=generate_random_string(); $cookie_str=serialize(array($user_id, $cookie_code)); setcookie('remember_me', $cookie_str, time() + 60*60*24*30, '/'); add_session("user/cookie",$cookie_code); } else { remove_session("user/cookie"); } // update session security $ip=$_SERVER['REMOTE_ADDR']; $session=session_id(); $cookie_code=get_session("user/cookie"); $cookie=md5($cookie_code); $DB->DoQuery("UPDATE `users` SET last_on=NOW(), session='$session'" .(($cookie_code!='')?", cookie='".$cookie."'":"") .", ip='$ip' WHERE id='$user_id' LIMIT 1"); // update session info $result=$DB->DoQuery("SELECT * FROM `users` WHERE id='$user_id' LIMIT 1"); $row=$DB->FetchAssoc($result); foreach($row as $k=>$v) { add_session("user/".$k,$v); } $DB->EndQuery($result); // check if any other part of your system needs to know about a user logging in. } function user_is_logged_in() { return get_session("user/id")!=0; } function generate_random_string($length=32) { $random=""; srand((double)microtime()*1000000); $char_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $char_list.= "abcdefghijklmnopqrstuvwxyz"; $char_list.= "1234567890"; for($i=0;$i<$length;++$i) { $random.=substr($char_list,(rand()%(strlen($char_list))), 1); } return $random; }