header('Location: ') problems

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
davisaggie
Forum Newbie
Posts: 16
Joined: Mon Aug 20, 2007 3:40 pm
Location: Salinas, CA

header('Location: ') problems

Post by davisaggie »

I am building an authentication module (code is below) and need some help getting header('Location: ') to work.

The goal for this module is to have login forms on different subdomains all use the same authentication module. If the authentication succeeds, the user will be directed to an appropriate protected section, otherwise they will be sent back to the login page they came from.

Problem 1:

header("Location: ".$_SERVER['REMOTE_ADDR']); results in a 404 error.

Is there a better way to redirect someone to the page they came from?

Problem 2:
After a successful login attempt has been made I generate a new session id for the person and store some information in the session variables, then use a switch statement to redirect the user to the correct page. At the next page for right now all I try to do is print out the information stored in the session array, but there does not seem to be anything there.

how can I propagate the session information using header('Location: admin/index.php'); for example?


Thanks.

Here's the code:

Code: Select all

<?php 
require_once('details.php');
require_once("../phpclass/securesession.class.php");
$clean_user = '';
$clean_pass = '';
session_start();
mysql_connect( "localhost", USER, PASS) or die("Cannot connect to MySQL Server");
mysql_select_db(DBNAME) or die("Cannot select database ".mysql_error());

$clean_user = mysql_real_escape_string($_POST['userid']);
$clean_pass = mysql_real_escape_string($_POST['pass']);

$user_query = '';
$user_query = "Select UserNum, UserID, Email, First, Last, Type, Location From user_auth ".
              "where UserID = '$clean_user' And Password = password('$pass')";
$user_result = '';
$user_result = mysql_query($user_query);
if (!$user_result){ 
	die("<br><b> $PHP_SELF </b>: ".mysql_error());}
else if (!mysql_num_rows($user_result)>0) {
	$_POST['login_failed'] = true;
	header("Location: ".$_SERVER['REMOTE_ADDR']);
}
else{
 	$ss = new SecureSession();
    $ss->check_browser = true;
    $ss->check_ip_blocks = 2;
    $ss->secure_word = 'SALT_';
    $ss->regenerate_id = true;
    $ss->Open();
    $_SESSION['logged_in'] = true;
	list($unum, $uid, $email, $first, $last, $type, $loc) = $user_result;
	$_SESSION['unum'] = $unum;
	$_SESSION['uid'] = $uid;
	$_SESSION['email'] = $email;
	$_SESSION['first'] = $first;
	$_SESSION['last'] = $last;
	$_SESSION['type'] = $type;
	$_SESSION['loc'] = $loc;
	switch($type){
		case 'GROWER':
		case 'grower':
		case 'Grower':	header('Location: grower/index.php');
			        break;
		case 'EDITOR':
		case 'editor':
		case 'Editor': header('Location: edit/index.php');
					   break;
		default: header('Location: auth/index.php');
                             break;		
	}
}
?>
The code on admin/index.php

Code: Select all

<h1> Welcome <?php echo($_SESSION['first'].' '.$_SESSION['last']); ?> </h1>
mcog_esteban
Forum Contributor
Posts: 127
Joined: Tue Dec 30, 2003 3:28 pm

Post by mcog_esteban »

About
Problem2:
From http://pt2.php.net/manual/en/function.header.php
Note: Session ID is not passed with Location header even if session.use_trans_sid is enabled. It must by passed manually using SID constant.
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

Regarding problem #1 - $_SERVER['REMOTE_ADDR'] is the user's IP address. I think you want $_SERVER['HTTP_REFERER']. Except you don't because that won't work all the time because it's optional whether the user's browser sends it.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

davisaggie wrote: The goal for this module is to have login forms on different subdomains all use the same authentication module. If the authentication succeeds, the user will be directed to an appropriate protected section, otherwise they will be sent back to the login page they came from.
header("Location: ".$_SERVER['REMOTE_ADDR']); results in a 404 error.
You're not redirecting them to the page they came from at all. You're redirecting them to the machine (their own pc or a proxy) that made the request...

In most common implementations i've seen of such a 'common authentication service' pass in a variable (post/get) with the name 'return_success' and 'return_failure'. Depending on the result of the authentication they are then redirected to one of these two values...
davisaggie wrote: Problem 2: After a successful login attempt has been made I generate a new session id for the person and store some information in the session variables, then use a switch statement to redirect the user to the correct page. At the next page for right now all I try to do is print out the information stored in the session array, but there does not seem to be anything there.
It's not entirely clear how you determine the validation was succesful at the 'authentication service' to start with? The authentication service should probably add a 'token' to the return_success url. Then the code at return_success should verifiy if this token was really issued by the 'authentication service'. And then you can regenerate the session_id and do whatever you like more... (In this setup the 'authorzation service' is not required to be in the same domain as the depending services..)
$user_query = "Select UserNum, UserID, Email, First, Last, Type, Location From user_auth ".
"where UserID = '$clean_user' And Password = password('$pass')";
I believe you made a mistake here, should be $clean_pass ;)
davisaggie
Forum Newbie
Posts: 16
Joined: Mon Aug 20, 2007 3:40 pm
Location: Salinas, CA

Post by davisaggie »

thanks for the tip about trying to redirect to $_SERVER['REMOTE_ADDR'] instead of $_SERVER['HTTP_REFERER']. That change fixed the first problem I was having.

reading through timvw's comments I see I didn't post the most current version of my module... oops :oops: it is below. I do plan on using some of timvw's suggestions in the future, but for now I am just trying to get the basic functionality of my module working before some of the extra security features are added.
About
Problem2:
From http://pt2.php.net/manual/en/function.header.php
Note: Session ID is not passed with Location header even if session.use_trans_sid is enabled. It must by passed manually using SID constant.
I read through the documentation better about the header function but still have a couple questions....
1) would it be better to use http_redirect() instead?
2) What is an SID constant, and how would I pass it?

Code: Select all

<?php 
require_once('details.php');
require_once("../phpclass/securesession.class.php");
$clean_user = '';
$clean_pass = '';
session_start();
mysql_connect( "localhost", USER, PASS) or die("Cannot connect to MySQL Server");
mysql_select_db(DBNAME) or die("Cannot select database ".mysql_error());

$clean_user = mysql_real_escape_string($_POST['userid']);
$clean_pass = mysql_real_escape_string(trim($_POST['pass']));

$user_query = '';
$user_query = "Select UserNum, UserID, Email, First, Last, Type, Location From user_auth ".
              "where UserID = '$clean_user' And Password = md5('$clean_pass')";
$user_result = '';
$user_result = mysql_query($user_query);
if (!$user_result){ 
	die("<br><b> $PHP_SELF </b>: ".mysql_error());}
else if (!mysql_num_rows($user_result)>0) {
	$_POST['login_failed'] = true;
	header("Location: ".$_SERVER['HTTP_REFERER']);
}
else{
 	$ss = new SecureSession();
    $ss->check_browser = true;
    $ss->check_ip_blocks = 2;
    $ss->secure_word = 'SALT_';
    $ss->regenerate_id = true;
    $ss->Open();
    $_SESSION['logged_in'] = true;
    list($unum, $uid, $email, $first, $last, $type, $loc) = mysql_fetch_row($user_result);
    /*die('uid: '.$uid.'</br>'.'name: '.$first.' '.$last.'</br>'.'type: '.$type);*/
	$_SESSION['unum'] = $unum;
	$_SESSION['uid'] = $uid;
	$_SESSION['email'] = $email;
	$_SESSION['first'] = $first;
	$_SESSION['last'] = $last;
	$_SESSION['type'] = $type;
	$_SESSION['loc'] = $loc;
	switch($type){
		case 'GROWER':  header('Location: grower/index.php'); break;
		case 'grower':  header('Location: grower/index.php'); break;
		case 'Grower':	header('Location: grower/index.php');
			        break;
		case 'EDITOR':
		case 'editor':
		case 'Editor': header('Location: edit/index.php');
					   break;
		default: header('Location: admin/index.php');	
	}
}
?>
davisaggie
Forum Newbie
Posts: 16
Joined: Mon Aug 20, 2007 3:40 pm
Location: Salinas, CA

Post by davisaggie »

Never mind question 2, I figured out about SID and how to send them. I still would like to know if using

http_redirect()

is better then

header('Location: ')

thanks,
Mike
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

http_redirect make it easier to do it right...

(Where your use of the location-header is not compliant, since you use relative urls, and yes we've seen postings about browsers that had/have problems with that....)
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

http_redirect() is in a PECL extension, whereas header() is part of the core.

I would go with header() every time since you can count on it being there. Besides, it's not that different anyway.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

I forgot to mention a thing... Use session_write_close if you depend on session variables being set before you issue the header ;)
Post Reply