Use header('Location:') instead. It's much more transparent to the browser. I use a similar mechanism on one of my sites.
I call
authenticate();
at the top of each page to check session and cookie data, basically to ensure that a session is loaded if cookie data checks out, but there is no existing session for transparent login. It is equivalent to your login.php, but it returns true if the user is logged in, else false. If the page requires a user to be logged in I call:
if ( ! authenticate() ) {
redirectToLogin(redirect=$PHP_SELF);
}
where redirect(url) is equivalent to header('Location: http://mydom.com/login.php?redirect=page/to/go/back/to/if/login/works')
login.php does all the form processing, display and cookie business, then, if login is successful, it redirects back to where it came from.
If you include a login form on every page pointing to login.php, you just get sent right back after you click "Login". It's a nice idiom, and works really well. I got the idea from looking at how a few big websites work.
I think you are definitely doing this the right way. Here's my authenticate.inc.php:
function authenticate_from_password( $user, $psswd )
{
global $DBPREFIX;
$query = "SELECT username, password FROM ". $DBPREFIX ."users WHERE
username=\"$user\" AND password = PASSWORD( '$psswd' )";
$res = mysql_query( $query ) or mysqlError();
if ( mysql_num_rows( $res ) == 0 ) {
return false;
} else {
load_user( $user );
return true;
}
}
/**
* Provides authentification from cookies.
*
* Authenticates user from security code cookie. If value and user match database entry, and
* the code is not too old, authentication will suceed. Returns true on success, false on failure.
* Function is public, but it is better to call authenticate(), which looks at session vars as well.
*
* @access public
* @param string $user Username.
* @param string $security Cookie value.
* @return Boolean
* @see authenticate()
*/
function authenticate_from_cookie( $user, $security )
{
// authenticate against security values in the DB
global $DBPREFIX, $COOKIELIMIT;
// first we delete all entries older than cookie limit
$user = trim($user);
$query = "DELETE FROM ". $DBPREFIX ."security WHERE ( UNIX_TIMESTAMP() - $COOKIELIMIT ) > time";
$res = mysql_query( $query ) or mysqlError();
$query = "SELECT id FROM ". $DBPREFIX ."security WHERE username = \"$user\"";
$res = mysql_query( $query ) or mysqlError();
if ( mysql_num_rows( $res ) == 0 ) {
return false;
}
$row = mysql_fetch_row( $res );
$res = $row[0];
if ( $res == $security ) {
return true;
} else { // not all cookies are present
return false;
}
}
/**
* Generate new security id.
*
* Creates a new security id for cookies, enters it into the database
* and returns it for setting in a cookie.
*
* @access public
* @param string $user Username
* @return string
*/
function new_security_key( $user )
{
global $DBPREFIX;
$id = md5( mt_rand(0, 9999999999) );
// delete old entry if there is one
$query = 'DELETE FROM '. $DBPREFIX .'security WHERE username = "'. $user .'"';
mysql_query( $query ) or mysqlError();
$query = "INSERT INTO ". $DBPREFIX ."security
( username, time, id ) VALUES
( \"$user\", UNIX_TIMESTAMP(), \"$id\" )";
mysql_query( $query ) or mysqlError();
return $id;
}
/**
* Loads user information from the database into session variables.
*
* Calls mysqlError() if query fails.
*
* @access public
* @param string $user Username.
* @return NULL
*/
function load_user( $user ) {
global $DBPREFIX;
$query = "SELECT id AS uid, realname, username AS user, type, owner, email,
popserver, popport, popuser, poppsswd, signature FROM ". $DBPREFIX ."users WHERE
username = '$user'";
$res = mysql_query( $query ) or mysqlError();
$arr = mysql_fetch_array( $res, MYSQL_ASSOC );
foreach ( $arr as $key=>$val ) {
$_SESSION[ $key ] = $val;
}
}
/**
* If no session and security cookie exists, starts a session automatically.
*
* Checks for username in session vars and then in cookie vars. If found, it authenticates the user.
* Returns 1 on succesful authentication, 0 on failure.
*
* @access public
* @return Boolean
*/
function authenticate()
{
global $db, $COOKIELIMIT;
if ( !( $_SESSION[ 'user' ] ) ) {
// check for security cookie
if ( $_COOKIE[ 'security' ] && $_COOKIE[ 'user' ] ) {
if ( !$db ) {
// open the database connection
$db = db_connect();
}
$res = authenticate_from_cookie( $_COOKIE[ 'user' ], $_COOKIE[ 'security' ] );
if ( $res ) {
// successful authentication
load_user( $_COOKIE[ 'user'] );
// refresh security cookie
//setcookie( 'security', $_COOKIE[ 'security' ], time() + $COOKIELIMIT, '/' );
return true;
} else {
// unsuccessful
return false;
}
}
} else {
// user already logged in
return true;
}
}
?>