Page 1 of 1

Excercuting login script using sessions

Posted: Sun Apr 03, 2005 8:34 am
by sn202
Hello people,

Basically I’m trying to use the following script to implement a secure login. I found this script in a php article and it looks very good, but as far as I can see its just a list of instructions saying how to do things rather than actually telling it to do anything. So if anyone could tell me how I would go about getting this script to execute that would be really helpfully.

cheers.

Code: Select all

<?php
error_reporting(E_ALL);
#connect to MYSQL
function &db_connect() {
	require_once 'DB.php';
	PEAR::setErrorHandling(PEAR_ERROR_DIE);
	$db_host = '****';
	$db_user = '****';
	$db_pass = '*****';
	$db_name = 'db_sn202';
	$dsn = "mysql://$db_user:$db_pass@unix+$db_host/$db_name";
	$db = DB::connect($dsn);
	$db->setFetchMode(DB_FETCHMODE_OBJECT);
	return $db;
}
session_start();
function session_defaults() {
	$_SESSION['logged'] = false;
	$_SESSION['uid'] = 0;
	$_SESSION['username'] = '';
	$_SESSION['cookie'] = 0;
	$_SESSION['remember'] = false;
}
if (!isset($_SESSION['uid']) ) {
	session_defaults();
}
class User {
	var $db = null; // PEAR::DB pointer
	var $failed = false; // failed login attempt
	var $date; // current date GMT
	var $id = 0; // the current user's id
	function User($db) {
		$this->db = $db;
		$this->date = $GLOBALS['date'];
		if ($_SESSION['logged']) {
			$this->_checkSession();
		} elseif ( isset($_COOKIE['mtwebLogin']) ) {
			$this->_checkRemembered($_COOKIE['mtwebLogin']);
		}
	}
	function _checkLogin($username, $password, $remember) {
		$username = $this->db->quote($username);
		$password = $this->db->quote(md5($password));
		$sql = "SELECT * FROM user WHERE " .
		"username = $username AND " .
		"password = $password";
		$result = $this->db->getRow($sql);
		if ( is_object($result) ) {
			$this->_setSession($result, $remember);
			return true;
		} else {
			$this->failed = true;
			$this->_logout();
			return false;
		}
	}
	function _setSession($values, $remember, $init = true) {
		$this->id = $values->id;
		$_SESSION['uid'] = $this->id;
		$_SESSION['username'] = htmlspecialchars($values->username);
		$_SESSION['cookie'] = $values->cookie;
		$_SESSION['logged'] = true;
		if ($remember) {
			$this->updateCookie($values->cookie, true);
			redirect();
		}
		if ($init) {
			$session = $this->db->quote(session_id());
			$ip = $this->db->quote($_SERVER['REMOTE_ADDR']);

			$sql = "UPDATE user SET session = $session, ip = $ip WHERE " .
			"id = $this->id";
			$this->db->query($sql);
			redirect();
		}
	}
	function updateCookie($cookie, $save) {
		$_SESSION['cookie'] = $cookie;
		if ($save) {
			$cookie = serialize(array($_SESSION['username'], $cookie) );
			set_cookie('mtwebLogin', $cookie, time() + 31104000, '/directory/');
		}
	}
	function _checkRemembered($cookie) {
		list($username, $cookie) = @unserialize($cookie);
		if (!$username or !$cookie) return;
		$username = $this->db->quote($username);
		$cookie = $this->db->quote($cookie);
		$sql = "SELECT * FROM user WHERE " .
		"(username = $username) AND (cookie = $cookie)";
		$result = $this->db->getRow($sql);
		if (is_object($result) ) {
			$this->_setSession($result, true);
		}
	}
	function _checkSession() {
		$username = $this->db->quote($_SESSION['username']);
		$cookie = $this->db->quote($_SESSION['cookie']);
		$session = $this->db->quote(session_id());
		$ip = $this->db->quote($_SERVER['REMOTE_ADDR']);
		$sql = "SELECT * FROM user WHERE " .
		"(username = $username) AND (cookie = $cookie) AND " .
		"(session = $session) AND (ip = $ip)";
		$result = $this->db->getRow($sql);
		if (is_object($result) ) {
			$this->_setSession($result, false, false);
		} else {
			$this->_logout();
		}
	}
	function redirect() {
		$name	= $_POST['username'];
		$sql2="select role from user where username='$name'";
		#exercute the query
		$rs2 = mysql_query( $sql2, $db )
		or die( mysql_error() );
		$row = mysql_fetch_object($rs2);
		#get number of rows that match username
		$num = mysql_numrows( $rs2 );
		#if there is a match the login is authenticated
		if( $num > 0 )
		Switch($row->role)
		{
			Case 'admin' :
			header("HTTP/1.1 301 Moved Permanently");
			header ("Location: http://www.****/admin/");
			header("Connection: close");
			break;
			Case 'leaner' :
			header("HTTP/1.1 301 Moved Permanently");
			header ("Location: http://www.****/learner/");
			header("Connection: close");
			break;
			Case 'instructor' :
			header("HTTP/1.1 301 Moved Permanently");
			header ("Location: http://www.****/instructor/");
			header("Connection: close");
			break;}
	}
}
?>

Login Script Using Sessions

Posted: Sun Apr 03, 2005 10:45 am
by marike
sn202 wrote: "if anyone could tell me how I would go about getting this script to execute that would be really helpfully."

Actually that script is a PHP Class called "User". It is not meant to excecute on its own. To use reference it in your new script with a 'require "User.class.php"'statement, create a new instance of the class "User", and use the methods (functions) defined in the class to create the functionality that you need, i.e. login a user.

You'll need to have PEAR installed on your system, and DB.php must be in your include_path. If all that's too much, I can post a script that uses MySQL and it's sha1 function for encryption of passwords for authentication, and sessions.

Hope this helps,

Posted: Sun Apr 03, 2005 10:54 am
by sn202
Hi,

Yeah, that would really help if you could post that script. I have a login script which I have created but it's not particularly secure and it uses cookies so wanted something a bit better. But as I am pressed for time that would really help and I'll probably come back to this when I have more time.

regards,

Simon.

Executing Login Script with Sessions

Posted: Sun Apr 03, 2005 2:10 pm
by marike
Here is the script I mentioned:

First you need to create your MySQL database:

Code: Select all

create database auth;
use auth;
create table authorised_users ( name varchar(20), 
                                password varchar(40),
                                        primary key     (name)
                              );

insert into authorised_users values ( 'testuser', 
                                      sha1('password') );
The password is encrypted with MySQL's sha1 function. Pretty cool.

Then the PHP Code is as follows:

Code: Select all

<?php
session_start();

if (isset($_POST['userid']) && isset($_POST['password']))
{
  // if the user has just tried to log in
  $userid = $_POST['userid'];
  $password = $_POST['password'];

 // change these values to ones for your MySQL connection
 $db_conn = new mysqli('localhost', 'myuser', 'mypass', 'auth');

  if (mysqli_connect_errno()) {
   echo 'Connection to database failed:'.mysqli_connect_error();
   exit();
  }

  $query = 'select * from authorised_users '
           ."where name='$userid' "
           ." and password=sha1('$password')";

  $result = $db_conn->query($query);
  if ($result->num_rows >0 )
  {
    // if they are in the database register the user id
    $_SESSION['valid_user'] = $userid;    
  }
  $db_conn->close();
}
?>
<html>
<body>
<h1>Home page</h1>
<? 
  if (isset($_SESSION['valid_user']))
  {
    echo 'You are logged in as: '.$_SESSION['valid_user'].' <br />';
    echo '<a href="logout.php">Log out</a><br />';
  }
  else
  {
    if (isset($userid))
    {
      // if they've tried and failed to log in
      echo 'Could not log you in.<br />';
    }
    else 
    {
      // they have not tried to log in yet or have logged out
      echo 'You are not logged in.<br />';
    }

    // provide form to log in 
    echo '<form method="post" action="authmain.php">';
    echo '<table>';
    echo '<tr><td>Userid:</td>';
    echo '<td><input type="text" name="userid"></td></tr>';
    echo '<tr><td>Password:</td>';
    echo '<td><input type="password" name="password"></td></tr>';
    echo '<tr><td colspan="2" align="center">';
    echo '<input type="submit" value="Log in"></td></tr>';
    echo '</table></form>';
  }
?>
<br />
<a href="index.php">Members section</a>
</body>
</html>
Just make sure you save the script to the name listed in the form action, 'authmain.php', and you'll be good to go. Hope this helps.

Posted: Sun Apr 03, 2005 3:53 pm
by sn202
Thanks for that, have implemented the script and everything, however I'm getting the following error:
Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /home/sn202/public_html/fyp/etrain/authmain.php:9) in /home/sn202/public_html/fyp/etrain/authmain.php on line 10

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /home/sn202/public_html/fyp/etrain/authmain.php:9) in /home/sn202/public_html/fyp/etrain/authmain.php on line 10

Fatal error: Cannot instantiate non-existent class: mysqli in /home/sn202/public_html/fyp/etrain/authmain.php on line 19

Posted: Sun Apr 03, 2005 4:12 pm
by feyd
viewtopic.php?t=1157 (sad, I have that url memorized now)

it would appear you don't have mysqli enabled. Look in phpinfo() to confirm. Note: mysql is not mysqli and vice versa.

From what I remember, mysqli started working in php5, and only works with or is intended for mysql 4+.

Login with Sessions

Posted: Sun Apr 03, 2005 4:28 pm
by marike
Feyd is absolutely right. Sorry about that. If I have time, maybe I'll rewrite the script using the plain mysql ext. I have tested it and it does work.

As far as the 'headers already sent' warning, you must no put anything before the call to session_start() in line 2.

Check that there is nothing before the first <?php start tag. Hope this helps.

As far as the mysqli extension, if you do have MySQL version 4.1 and above it is pretty simple to install on Windows. For me, I had to recompile PHP 5 on my Mac OS X, but on Windows you just need to add this line 'extension=php_mysqli.dll' to you php.ini. And I'm pretty sure you'll need to drag the appropriate .dll file in to your WIN 32 system folder. At least that is how I remember doing it on my Windows box. Some of the other 'real' Windows users can probably help you out here. Of course, the preceeding is all moot is you don't have MySQL 4.1+.

Good luck,

Posted: Sun Apr 03, 2005 4:32 pm
by sn202
Hi, yeah that's probably it. I'm using PHP version 4.3.2. However I’ve checked in phpinfo() but mysqli doesn't seem to be in there. I'm hosted on a Linux apache web sever, however I don't have access to the configuration of it.

cheers anyway, I'll have a play around and see what I can come up with, unless anyone can come up with anything?

regards,

Simon.

Here you go sn202 - code with plain mysql

Posted: Sun Apr 03, 2005 7:01 pm
by marike
I recoded it replacing the mysqli calls with mysql. Tested it and it works fine.

Code: Select all

<?php
session_start();

if (isset($_POST['userid']) && isset($_POST['password']))
{
  // if the user has just tried to log in
  $userid = $_POST['userid'];
  $password = $_POST['password'];
  
  $db_conn = mysql_connect('localhost', 'username', 'password', 'auth');
  
  if(!$db_conn) {
  	die('Could not connect: ' .mysql_error());
  }

  $query = 'select * from authorised_users '
           ."where name='$userid' "
           ." and password=sha1('$password')";
           
  $result = mysql_query($query);
  if(mysql_num_rows($result) > 0)
  {
	 // if they are in the database register the user id
    $_SESSION['valid_user'] = $userid;    
  }
  mysql_close($db_conn);
}
?>
<html>
<body>
<h1>Home page</h1>
<?php 
  if (isset($_SESSION['valid_user']))
  {
    echo 'You are logged in as: '.$_SESSION['valid_user'].' <br />';
    echo '<a href="logout.php">Log out</a><br />';
  }
  else
  {
    if (isset($userid))
    {
      // if they've tried and failed to log in
      echo 'Could not log you in.<br />';
    }
    else 
    {
      // they have not tried to log in yet or have logged out
      echo 'You are not logged in.<br />';
    }

    // provide form to log in 
    echo '<form method="post" action="authmain.php">';
    echo '<table>';
    echo '<tr><td>Userid:</td>';
    echo '<td><input type="text" name="userid"></td></tr>';
    echo '<tr><td>Password:</td>';
    echo '<td><input type="password" name="password"></td></tr>';
    echo '<tr><td colspan="2" align="center">';
    echo '<input type="submit" value="Log in"></td></tr>';
    echo '</table></form>';
  }
?>
<br />
<a href="index.php">Members section</a>
</body>
</html>
Just remember to create your MySQL database table first which is at the top of this post, and name this script whatever's in the form action, in this case, authmain.php. Your all set. Sorry about before and the mysqli code. I forget that most webhosts, including the one I have a site on, do not have PHP 5, but usually 4.3. Hope this helps.

Oh, and remember don't put any code at all before the opening <?php tag, and you'll be OK.

Posted: Mon Apr 04, 2005 1:58 pm
by sn202
Hi all,

I'm using the above login script, but i'm getting an error message saying:
Warning: mysql_numrows(): supplied argument is not a valid MySQL result resource in /home/sn202/public_html/fyp/etrain/authmain.php on line 21
Any ideas?

Regards,

Simon.

Posted: Mon Apr 04, 2005 2:53 pm
by feyd
invalid query. echo $query. Add 'or die(mysql_error())' to mysql_query like so:

Code: Select all

$result = mysql_query( $query ) or die(mysql_error());

Login using sessions: Solved.

Posted: Mon Apr 04, 2005 3:19 pm
by sn202
yeah of course, cheers mate, always the little things!

here's my working script incase anyone finds it useful:

Code: Select all

<?php
session_start();
 
if (isset($_POST['userid']) && isset($_POST['password']))
{
  // if the user has just tried to log in
  $userid = $_POST['userid'];
  $password = $_POST['password'];
  
  $db_conn = mysql_connect('localhost', 'username', 'password', 'auth');
  
  if(!$db_conn) {
      die('Could not connect: ' .mysql_error());
  }
 
  $rs = @mysql_select_db ( "db_sn202", $db_conn )
			or die( mysql_error()  );
			
  $query = 'select * from authorised_users '
           ."where name='$userid' "
           ." and password=sha1('$password')";
           
  $result = mysql_query( $query ) or die(mysql_error());
  if(mysql_num_rows($result) > 0)
  {
     // if they are in the database register the user id
    $_SESSION['valid_user'] = $userid;    
  }
  mysql_close($db_conn);
}
?>
<html>
<body>
<h1>Home page</h1>
<?php 
  if (isset($_SESSION['valid_user']))
  {
    echo 'You are logged in as: '.$_SESSION['valid_user'].' <br />';
    echo '<a href="logout.php">Log out</a><br />';
  }
  else
  {
    if (isset($userid))
    {
      // if they've tried and failed to log in
      echo 'Could not log you in.<br />';
    }
    else 
    {
      // they have not tried to log in yet or have logged out
      echo 'You are not logged in.<br />';
    }
 
    // provide form to log in 
    echo '<form method="post" action="authmain.php">';
    echo '<table>';
    echo '<tr><td>Userid:</td>';
    echo '<td><input type="text" name="userid"></td></tr>';
    echo '<tr><td>Password:</td>';
    echo '<td><input type="password" name="password"></td></tr>';
    echo '<tr><td colspan="2" align="center">';
    echo '<input type="submit" value="Log in"></td></tr>';
    echo '</table></form>';
  }
?>
<br />
<a href="index.php">Members section</a>
</body>
</html>
Thanks everyone that helped,

Regards,

Simon.

Excecuting login script using sessionsLogin Script

Posted: Tue Apr 05, 2005 8:16 am
by marike
I'm glad it is working for you. Worked fine when I posted it, in fact it I've used it in projects.

I just wanted to point out that now, you are selecting a database both on line 10 with mysql_connect and on line 16 with mysql_select_db. If you use the latter, you should probably remove the first 'auth'.

As Feyd alluded to, the only reason for $query not be a valid MySQL resource is the connection failed in some way, probably couldn't select a database for some reason. Oh, well.

Excercuting login script using sessions

Posted: Tue Apr 05, 2005 8:25 am
by marike
sn202 wrote:
"here's my working script incase anyone finds it useful:"

Sorry but this line just bugs me. You changed one line to the script that I posted and now it's your "working script incase somebody finds it useful".

Maybe you didn't mean it the way it came off, but I don't think I'll be posting anymore complete, working scripts.

I hope the rest find it useful.

Excecuting login script using sessions

Posted: Tue Apr 05, 2005 5:06 pm
by marike
Actually I have a question about the version of the script you posted in these specific lines:

Code: Select all

<?php
session_start();
 
if (isset($_POST['userid']) && isset($_POST['password']))
{
  // if the user has just tried to log in
  $userid = $_POST['userid'];
  $password = $_POST['password'];
  
  $db_conn = mysql_connect('localhost', 'username', 'password', 'auth');
  
  if(!$db_conn) {
      die('Could not connect: ' .mysql_error());
  }
 
  $rs = @mysql_select_db ( "db_sn202", $db_conn )
            or die( mysql_error()  );
            
If you use mysql_select_db to select your database "db_sn202",
what does 'auth' in line 10 represent?

Your database named 'db_sn202', instead of 'auth' is the reason for the error: 'the supplied argument is not a valid MySQL result resource'. All you have to do in this case is change 'auth', the database named in the SQL code that I posted above, to 'db_sn202'. You can then safely remove the lines 16

Code: Select all

$rs = @mysql_select_db ( "db_sn202", $db_conn )
            or die( mysql_error()  );
Otherwise, "your" code does not make sense.

Essentially, both versions of the scripts that I originally posted, the mysqli and the mysql version worked perfectly. But if you change the name of your database, that change has to be reflected in line 10, the mysql_connect statement where the four arguments to the mysql_connect function are "dbhost", "dbuser", "dbpassword", and "dbname".

Hope this helps.