Excercuting login script using sessions

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
sn202
Forum Commoner
Posts: 36
Joined: Thu Dec 16, 2004 7:30 pm

Excercuting login script using sessions

Post 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;}
	}
}
?>
marike
Forum Newbie
Posts: 24
Joined: Thu Mar 31, 2005 6:19 pm
Location: New York

Login Script Using Sessions

Post 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,
sn202
Forum Commoner
Posts: 36
Joined: Thu Dec 16, 2004 7:30 pm

Post 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.
marike
Forum Newbie
Posts: 24
Joined: Thu Mar 31, 2005 6:19 pm
Location: New York

Executing Login Script with Sessions

Post 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.
sn202
Forum Commoner
Posts: 36
Joined: Thu Dec 16, 2004 7:30 pm

Post 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
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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+.
marike
Forum Newbie
Posts: 24
Joined: Thu Mar 31, 2005 6:19 pm
Location: New York

Login with Sessions

Post 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,
sn202
Forum Commoner
Posts: 36
Joined: Thu Dec 16, 2004 7:30 pm

Post 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.
marike
Forum Newbie
Posts: 24
Joined: Thu Mar 31, 2005 6:19 pm
Location: New York

Here you go sn202 - code with plain mysql

Post 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.
sn202
Forum Commoner
Posts: 36
Joined: Thu Dec 16, 2004 7:30 pm

Post 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.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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());
sn202
Forum Commoner
Posts: 36
Joined: Thu Dec 16, 2004 7:30 pm

Login using sessions: Solved.

Post 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.
marike
Forum Newbie
Posts: 24
Joined: Thu Mar 31, 2005 6:19 pm
Location: New York

Excecuting login script using sessionsLogin Script

Post 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.
marike
Forum Newbie
Posts: 24
Joined: Thu Mar 31, 2005 6:19 pm
Location: New York

Excercuting login script using sessions

Post 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.
marike
Forum Newbie
Posts: 24
Joined: Thu Mar 31, 2005 6:19 pm
Location: New York

Excecuting login script using sessions

Post 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.
Post Reply