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; }
I am try to run the code. but the error say there is a missing function of:
1. add_session()
2. remove_session()
3. get_session()
Any idea? Thank 1st.
add_session(a,b) and set_session(a,b) both do $_SESSION[a]=b;
get_session(a) returns $_SESSION[a];
remove_session(a) does unset($_SESSION[a]);
In some systems where customers are paranoid about XSS attacks I can replace $_SESSION with something else and I don’t have to change thousands of references in my code.
Thanks! You’re the first real person to comment on this blog. Hooray for you!
Thank, How about account_login() function? it is to clear all cookie and close session?
account_login() creates the cookie/session data to remember that you are logged in. At the end of account_login() is where you would add any extra commands – maybe a “welcome, user!” message or redirect to a different page.
How about add_notice() and add_error() functions?
I’ve written a new, easier version with better code and examples. Please let me know if that helps!
http://www.marginallyclever.com/2009/09/forms-simplified/
Admin, your answer was about another script, can you put the full code of your login handling, please.
because I’ve not suc when i try to showing notices on the login page.
Thanks for the source. Couldn’t find the “new, easier version”. But the current one seems to work just fine for my purposes