Looking for inputs on my cookie/session authentication class, not sure if i got it correct
Im currently creating my own forum for my website and i have read plenty of topics on cookie/session authentication and i think im aware of the attacks etc that exists. I get that its not 100% secure but im trying to do it as safe as possible.

Im currently storing IP in the cookie and im aware that some might have problems with that but im going to change to check the first 2 blocks of the IP instead. I dont think its going to be a problem since 95% of the people in Sweden got broadband which rarely changes IP.

Something that im really insecure about is the session_start which i do need later for forms etc what is the best practice to implement it? im pretty sure that im doing that thing pretty much wrong.

Any inputs is much appreciated!

Best Regards
John


    Class
    	class user2
    	{
    		private $db = null;
    		private $cookie_salt = '!!PLonSIMDSAM35324dfg5DAUSHODNASDJ353NMASDSA&%&A/SD&HASNJDdfghAS&DGIHYAUSDNA3535SDFASDF%A3532dfgsdfggsdg53532535SDGIASYDU';
    		
    		var $user_ip = false;
    		var $user_id = false;
    		var $user_username = false;
    		var $cookie_identifier = false;
    		var $user_logged_in = false;
    		
    	    function __construct()
    	    {
    			global $mysql_server;
    			global $mysql_user;
    			global $mysql_password;
    			global $mysql_database_name;
    						
    			$this->db = new database($mysql_server, $mysql_user, $mysql_password, $mysql_database_name, true);
    			
    			$this->checkUserAuthentication();
    	    }
    
    	
    		public function Login($input_username, $input_user_password)
    		{
    			// If empty parameters return false
    			if (empty($input_username) || empty($input_user_password))
    			{
    				return false;
    			}
    			
    			$user_login = $this->db->q("SELECT user_id, username FROM `forum_user` WHERE username = ? AND password = ? LIMIT 1", 'ss' , $input_username, $input_user_password);
    			if ($user_login != false)
    			{
    				$this->user_ip = $_SERVER['REMOTE_ADDR'];
    				$this->user_id = $user_login[0]['user_id'];
    				$this->user_username = $user_login[0]['username'];
    
    				if($this->initiateSessionCookie() == true)
    				{
    					$this->user_logged_in = true;
    					return true;
    				}
    				else
    				{
    					return false;
    				}
    			}
    			else
    			{
    				return false;
    			}
    		}
    
    		private function initiateSessionCookie()
    		{
    			// Delete old sessions from this user or USE REPLACE instead
    			$this->db->q("DELETE FROM `forum_session` WHERE userid = ?", 'i' , $this->user_id);
    
    			$identifier = md5($this->cookie_salt . md5($this->user_username . $this->user_ip) . $this->cookie_salt);
    			$token = md5($this->generateToken());
    			$timeout = time() + 60 * 60 * 24 * 7;  // 7 days
    			$timeout_minutes = 10080; // 7 days
    			$init_session = $this->db->q("INSERT INTO forum_session SET session = ? 
    																	  , token = ? 
    																	  , userid = ? 
    																	  , sess_start = now() 
    																	  , last_activity = now() 
    																	  , sess_expire = DATE_ADD(curdate(),INTERVAL ? MINUTE) 
    																	  , ip = ?", 'ssiis' , $identifier, $token, $this->user_id, $timeout_minutes, $this->user_ip);
    			if($init_session != false) {
    				setcookie('auth', "$identifier:$token", $timeout);
    				return true;
    			}
    			else {
    				return false;
    			}
    		}
    
    		private function generateToken()
    		{
    			$chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz!#&";
    
    			for($i = 1; $i <= 20; $i++)
    			{
    				$rand_number = rand(0, 59);
    				$random_string .= $chars[$rand_number];
    			}
    			return $random_string;
    		}
    	    
    	    private function checkUserAuthentication()
    	    {
    	    	$this->user_logged_in = false;
    	    	
    	    	list($_cookie_identifier, $_cookie_token) = explode(':', $_COOKIE['auth']);
    	    	
    	    	if(ctype_alnum($_cookie_identifier) && ctype_alnum($_cookie_token))
    	    	{
    	    		$_cookie_data['identifier'] = $_cookie_identifier;
    	    		$_cookie_data['token'] = $_cookie_token;
    	    	}
    	    	else
    	    	{
    	    		return false;
    	    	}
    	    	
    	    	$auth_user = $this->db->q("SELECT * 
    									   FROM forum_session a 
    									   LEFT JOIN 
    											forum_user b ON a.userid = b.user_id 
    									   WHERE 
    											a.session = ? AND 
    											a.token = ? 
    									   LIMIT 1", 'ss' , $_cookie_data['identifier'], $_cookie_data['token']);
    			if($auth_user != false)
    			{
    				if(time() > strtotime($auth_user[0]['sess_expire']))
    				{
    					return false;
    				}
    
    				if($_cookie_data['identifier'] == md5($this->cookie_salt . md5($auth_user[0]['username'] . $_SERVER['REMOTE_ADDR']) . $this->cookie_salt))
    				{
    					$this->user_logged_in = true;
    					
    					$this->user_id = $auth_user[0]['user_id']; 
    					$this->user_username = $auth_user[0]['username']; 
    					$this->user_ip = $_SERVER['REMOTE_ADDR'];
    
    					return true;
    					
    					// TODO list
    					// Renew token every 5 min? 
    					// Renew cookie expire date
    					// Renew session expire date
    				}
    				else
    				{
    					return false;
    				}
    			}
    			else
    			{
    	    		return false;
    			}
    	    }
    	    
    		public function isUserLoggedIn()
    		{
    			return $this->user_logged_in;
    		}
    
    	}

The session handler which i include in all pages on the forum.

     require_once('classes/user2.class.php');
     $user = new User2();
     session_start();

Looking for inputs on my cookie/session authentication class, not sure if i got it correct
===

Im currently creating my own forum for my website and i have read plenty of topics on cookie/session authentication and i think im aware of the attacks etc that exists. I get that its not 100% secure but im trying to do it as safe as possible.

Im currently storing IP in the cookie and im aware that some might have problems with that but im going to change to check the first 2 blocks of the IP instead. I dont think its going to be a problem since 95% of the people in Sweden got broadband which rarely changes IP.

Something that im really insecure about is the session_start which i do need later for forms etc what is the best practice to implement it? im pretty sure that im doing that thing pretty much wrong.

Any inputs is much appreciated!

Best Regards
John


    Class
    	class user2
    	{
    		private $db = null;
    		private $cookie_salt = '!!PLonSIMDSAM35324dfg5DAUSHODNASDJ353NMASDSA&%&A/SD&HASNJDdfghAS&DGIHYAUSDNA3535SDFASDF%A3532dfgsdfggsdg53532535SDGIASYDU';
    		
    		var $user_ip = false;
    		var $user_id = false;
    		var $user_username = false;
    		var $cookie_identifier = false;
    		var $user_logged_in = false;
    		
    	    function __construct()
    	    {
    			global $mysql_server;
    			global $mysql_user;
    			global $mysql_password;
    			global $mysql_database_name;
    						
    			$this->db = new database($mysql_server, $mysql_user, $mysql_password, $mysql_database_name, true);
    			
    			$this->checkUserAuthentication();
    	    }
    
    	
    		public function Login($input_username, $input_user_password)
    		{
    			// If empty parameters return false
    			if (empty($input_username) || empty($input_user_password))
    			{
    				return false;
    			}
    			
    			$user_login = $this->db->q("SELECT user_id, username FROM `forum_user` WHERE username = ? AND password = ? LIMIT 1", 'ss' , $input_username, $input_user_password);
    			if ($user_login != false)
    			{
    				$this->user_ip = $_SERVER['REMOTE_ADDR'];
    				$this->user_id = $user_login[0]['user_id'];
    				$this->user_username = $user_login[0]['username'];
    
    				if($this->initiateSessionCookie() == true)
    				{
    					$this->user_logged_in = true;
    					return true;
    				}
    				else
    				{
    					return false;
    				}
    			}
    			else
    			{
    				return false;
    			}
    		}
    
    		private function initiateSessionCookie()
    		{
    			// Delete old sessions from this user or USE REPLACE instead
    			$this->db->q("DELETE FROM `forum_session` WHERE userid = ?", 'i' , $this->user_id);
    
    			$identifier = md5($this->cookie_salt . md5($this->user_username . $this->user_ip) . $this->cookie_salt);
    			$token = md5($this->generateToken());
    			$timeout = time() + 60 * 60 * 24 * 7;  // 7 days
    			$timeout_minutes = 10080; // 7 days
    			$init_session = $this->db->q("INSERT INTO forum_session SET session = ? 
    																	  , token = ? 
    																	  , userid = ? 
    																	  , sess_start = now() 
    																	  , last_activity = now() 
    																	  , sess_expire = DATE_ADD(curdate(),INTERVAL ? MINUTE) 
    																	  , ip = ?", 'ssiis' , $identifier, $token, $this->user_id, $timeout_minutes, $this->user_ip);
    			if($init_session != false) {
    				setcookie('auth', "$identifier:$token", $timeout);
    				return true;
    			}
    			else {
    				return false;
    			}
    		}
    
    		private function generateToken()
    		{
    			$chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz!#&";
    
    			for($i = 1; $i <= 20; $i++)
    			{
    				$rand_number = rand(0, 59);
    				$random_string .= $chars[$rand_number];
    			}
    			return $random_string;
    		}
    	    
    	    private function checkUserAuthentication()
    	    {
    	    	$this->user_logged_in = false;
    	    	
    	    	list($_cookie_identifier, $_cookie_token) = explode(':', $_COOKIE['auth']);
    	    	
    	    	if(ctype_alnum($_cookie_identifier) && ctype_alnum($_cookie_token))
    	    	{
    	    		$_cookie_data['identifier'] = $_cookie_identifier;
    	    		$_cookie_data['token'] = $_cookie_token;
    	    	}
    	    	else
    	    	{
    	    		return false;
    	    	}
    	    	
    	    	$auth_user = $this->db->q("SELECT * 
    									   FROM forum_session a 
    									   LEFT JOIN 
    											forum_user b ON a.userid = b.user_id 
    									   WHERE 
    											a.session = ? AND 
    											a.token = ? 
    									   LIMIT 1", 'ss' , $_cookie_data['identifier'], $_cookie_data['token']);
    			if($auth_user != false)
    			{
    				if(time() > strtotime($auth_user[0]['sess_expire']))
    				{
    					return false;
    				}
    
    				if($_cookie_data['identifier'] == md5($this->cookie_salt . md5($auth_user[0]['username'] . $_SERVER['REMOTE_ADDR']) . $this->cookie_salt))
    				{
    					$this->user_logged_in = true;
    					
    					$this->user_id = $auth_user[0]['user_id']; 
    					$this->user_username = $auth_user[0]['username']; 
    					$this->user_ip = $_SERVER['REMOTE_ADDR'];
    
    					return true;
    					
    					// TODO list
    					// Renew token every 5 min? 
    					// Renew cookie expire date
    					// Renew session expire date
    				}
    				else
    				{
    					return false;
    				}
    			}
    			else
    			{
    	    		return false;
    			}
    	    }
    	    
    		public function isUserLoggedIn()
    		{
    			return $this->user_logged_in;
    		}
    
    	}

The session handler which i include in all pages on the forum.

     require_once('classes/user2.class.php');
     $user = new User2();
     session_start();
