Forum Moderators: coopster

Message Too Old, No Replies

Login, get value, redirect and protect

redirect, session, php, mysql

         

Awful newbie

11:06 pm on Mar 28, 2007 (gmt 0)

10+ Year Member



Ok. I am a Awnful Newbie. I want to let users log in, get their username and password verfied against my mysql-db, and each user are associated with one of five accessgroups, named by "A", "B" ... "E".

My db have these fields:

username password accessgroup

Users with username and password matched from the db assosicated by for example "B" should then be redirected to a special page, a page which should not be accessible by any other goups of users. And so on.

This might perhaps be solved with sessions?

Is it anyone who can help me get started, hopefully with some code? I am not looking for anything advanced and sophisticated, no encryption etc.

eelixduppy

11:11 pm on Mar 28, 2007 (gmt 0)



Welcome to WebmasterWorld!

Surely you know more than you give yourself credit for ;)

>> help me get started

We have a great thread from our library titled PHP User Authentication and Passwords [webmasterworld.com] that should get you on your way. This thread has been reviewed so don't forget to also read the Peer Code Review [webmasterworld.com] that goes along with this.

Other references include php's MySQL Functions [us2.php.net] and [mysql.com...]

As for the redirect, you are going to want to use header [php.net] to set the Location header. Baby steps first, though, so get the authentication working first! ;)

I wish you luck with your learning of PHP. If you run into any roadblocks along the way, feel free to ask; there will always be someone here who can answer it.

Good luck! :)

Awful newbie

8:45 am on Mar 29, 2007 (gmt 0)

10+ Year Member



Ok. I have made this, but it's not working as I hoped. The idea is that the users log in with their customer_number and customer_pass. Associated with these are a destinationID, and if correct combination og customer_number and customer_pass and destinationID they are redirected to a specific file. These files are supposed to be accessible only to the users with the correct combinations og customer_number, customer_pass and destinationID. (All customer_number and customer_pass are stored unencrypted in the db).

Is it anyone who can see what is not correct with this script?

<?php

session_start();

$username = $_POST['username'];
$userpass = md5($_POST['userpass']);

//my mysql login details
$host="ip.to.my.dbhost";
$username="my_username";
$password="my_password";
$db_name="my_db";
$tbl_name="my_table";

// connect and choose db
mysql_connect("$host", "$username", "$password")or die("I cant connect");
mysql_select_db("$db_name")or die("I can't choose db");

//process search
$sql="SELECT destinationID FROM $tbl_name WHERE customer_number='$customer_number' AND customer_pass='$customer_pass'";
$result=mysql_query($sql);

if( $result ) {
$row = mysql_fetch_array($result);


//register user session
$_SESSION['customer_number'] = "$customer_number";
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}

//choose correct destination based upon users data from mysql

switch($row['destinationID']) {
case '10':
header("location:/customer/cat10/index.php");
break;
case '20':
header("location:/customer/cat20/index.php");
break;
case '30':
header("location:/customer/cat30/index.php");
break;
case '40':
header("location:/customer/cat40/index.php");
break;
case '50':
header("location:/customer/cat50/index.php");
break;
default:
printf("Wrong username or password<br>\n");
}

?>

On top of all protected index-files:

<?php
session_start();
$newip = $_SERVER['REMOTE_ADDR'];
if (!isset($_SESSION['customer_number']) ¦¦ empty($_SESSION['customer_number']) ¦¦ $newip!= $_SESSION['ip']) { include "logout.php"; }
?>

(and logout php would just be a call to session_destroy(); -right?)

adb64

9:26 am on Mar 29, 2007 (gmt 0)

10+ Year Member



Hello Awful newbie,

What exactly isn't working in your script?

The location header should be a complete URL:
header("location: http://www.example.com/customer/cat10/index.php");

[edited by: eelixduppy at 11:12 am (utc) on Mar. 29, 2007]
[edit reason] use example.com, please [/edit]

Awful newbie

9:41 am on Mar 29, 2007 (gmt 0)

10+ Year Member



If I try to access some of the protected files without having logged in, I get straight in. Further, after login and redirect the traget page turns blank, and it seems as if the script doesn't need correct login details, I can get there without the correct login details.

[edited by: Awful_newbie at 10:13 am (utc) on Mar. 29, 2007]

whoisgregg

1:05 pm on Mar 29, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



(and logout php would just be a call to session_destroy(); -right?)

Actually, logout.php (in your setup) would need to display an error page then

die;

Just destroying the session doesn't prevent the rest of the page from displaying.

Angelis

1:12 pm on Mar 29, 2007 (gmt 0)

10+ Year Member



$sql="SELECT destinationID FROM $tbl_name WHERE customer_number='$customer_number' AND customer_pass='$customer_pass'";

Wrong variables...

Awful newbie

1:58 pm on Mar 29, 2007 (gmt 0)

10+ Year Member



Thanks, I corrected the variables, but still I get just one destination and also regardless if user input actuelly are equal or not to the data in the db.

And the protected pages are widely open, I can access them all directly and no session requirement are preventing me from doing that. The meaning was that when users verified their username and password the script associated these with the correct destinationID and forwarded the user there. When there, the users session data allows them to access that page, and only that one.
That was the idea. But something is wrong. I really hope some of you skilled people are able to help me to locate the errors :-)

Angelis

2:23 pm on Mar 29, 2007 (gmt 0)

10+ Year Member



Should it be

SELECT accessgroup

?

Awful newbie

3:08 pm on Mar 29, 2007 (gmt 0)

10+ Year Member



No, the redirect now works according to the users input of username and password associated with their correct destinationID.

But the session part doesnt work at all. The meaning is that each user should only be able to access the page they are redirected to, and it should not be possible to snoop in the protected files in their directorys without beein logged in the proper way. I thought session was the way to solve it, but I really don't know how to to this.

This code is in top of each of the destinationIDs paths: (index.php)

<?php session_start();
$newip = $_SERVER['REMOTE_ADDR'];
if (!isset($_SESSION['customer_number']) ¦¦ empty($_SESSION['customer_number']) ¦¦ $newip!= $_SESSION['ip']) { include "logout.php"; }
?>

But it doesnt protect, the only thing it does is to produce a blank page when going there...

whoisgregg

5:26 pm on Mar 29, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In order to check whether the user is authorized to see a particular page, you need to check their access privileges against the page they are trying to access.

Sticking with your current approach, populate another session variable with their destinationID:

$_SESSION['destinationID'] = $row['destinationID'];

Then, on the protected pages, compare the values:

preg_match('/cat([0-9]+)/', $_SERVER['REQUEST_URI'], $currentID);
$currentID = (isset($currentID))? $currentID[1] : null;
// two lines above are untested, purpose is to populate $currentID with the correct numeric value
if (
!isset($_SESSION['customer_number']) ¦¦
empty($_SESSION['customer_number']) ¦¦
$newip != $_SESSION['ip'] ¦¦
!isset($currentID ) ¦¦
$currentID==null ¦¦
$_SESSION['destinationID'] != $currentID
){
echo 'Logged out.'; // for debugging, comment out or delete before posting live
include "logout.php";
}

Awful newbie

7:11 pm on Mar 29, 2007 (gmt 0)

10+ Year Member



Thanks for the reply! But still it's fully possible to snoop in the protcted files...

Here is the processing script:

<?php

session_start();

$customer_number = $_POST['customer_number'];
$customer_pass = $_POST['customer_pass'];

//my mysql login details
$host="ip.to.my.dbhost";
$username="my_username";
$password="my_password";
$db_name="my_db";
$tbl_name="my_table";

// connect and choose db
mysql_connect("$host", "$username", "$password")or die("I cant connect");
mysql_select_db("$db_name")or die("I can't choose db");

//process search
$sql="SELECT destinationID FROM $tbl_name WHERE customer_number='$customer_number' AND customer_pass='$customer_pass'";
$result=mysql_query($sql);

if( $result ) {
$row = mysql_fetch_array($result);

//register user session
$_SESSION['customer_number'] = "$customer_number";
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['destinationID'] = $row['destinationID'];
}

//choose correct destination based upon users data from mysql

switch($row['destinationID']) {
case '10':
header("location:http://www.example.com/customer/cat10/index.php");
break;
case '20':
header("location:http://www.example.com/customer/cat20/index.php");
break;
case '30':
header("location:http://www.example.com/customer/cat30/index.php");
break;
case '40':
header("location:http://www.example.com/customer/cat40/index.php");
break;
case '50':
header("location:http://www.example.com/customer/cat50/index.php");
break;
default:
printf("Wrong username or password<br>\n");
}

?>

And here is on of the protected index-files:
(the file showed in browser is blank...)

<?php session_start();
//$newip = $_SERVER['REMOTE_ADDR'];
//if (!isset($_SESSION['customer_number']) ¦¦ empty($_SESSION['customer_number']) ¦¦ $newip!= $_SESSION['ip']) { include "logout.php"; }
//I commented these out, since they were not visible in the reply I got from you

preg_match('/cat([0-9]+)/', $_SERVER['REQUEST_URI'], $currentID);
$currentID = (isset($currentID))? $currentID[1] : null;
// two lines above are untested, purpose is to populate $currentID with the correct numeric value
if (
!isset($_SESSION['customer_number']) ¦¦
empty($_SESSION['customer_number']) ¦¦
$newip!= $_SESSION['ip'] ¦¦
!isset($currentID ) ¦¦
$currentID==null ¦¦
$_SESSION['destinationID']!= $currentID
){
echo 'Logged out.'; // for debugging, comment out or delete before posting live
include "logout.php";
}

?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Granted</title>
</head>
<body>This is supposed to show up after success login.
</body>
</html>

whoisgregg

7:53 pm on Mar 29, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You probably already did this, but make sure you replace the broken pipe characters "¦¦" with solid pipe characters before running the code. (WebmasterWorld forum software breaks the pipes and PHP chokes on them.)

Also, uncomment this line as the $newip variable is needed in the if block lower down on the page:

//$newip = $_SERVER['REMOTE_ADDR'];

And add the code below in blue to the end of the php block as indicated:

include "logout.php"; 
} [blue]else {
echo 'Logged in.'; // for debugging, comment out before posting live
}[/blue]

You can safely delete this line: (All the conditions it tests are present in the if statement below it.)

//if (!isset($_SESSION['customer_number']) ¦¦ empty($_SESSION['customer_number']) ¦¦ $newip!= $_SESSION['ip']) { include "logout.php"; } 

Last but not least, add the bit in blue to the top of your script:

<?php
[blue]error_reporting(E_ALL);[/blue]
session_start();

Ultimately, you'll need to echo all the different variables present to see what values they contain and debug from there. Determine what isn't being set correctly and change how you set those variables.

Awful newbie

8:44 pm on Mar 29, 2007 (gmt 0)

10+ Year Member



Thanks, I did what you said, and I also corrected the pipes.

Using echo on the protected page, I found that I get the customer_number and the IP. But I don't get the destinationID.

The pages are still unprotected, I can access them by typing the url. I will sincerely be really happy for all further help, maybe the answere to this quest is very near.

eelixduppy

8:50 pm on Mar 29, 2007 (gmt 0)



Try adding the bolded code after the included logout.php script:

include "logout.php";
[b]exit;[/b]

This will prevent any further action and terminate the script.

Awful newbie

9:14 pm on Mar 29, 2007 (gmt 0)

10+ Year Member



Adding the exit;
produces just a blank page... (correctly redirected, but not protected).
Anyone with any possible solution?

eelixduppy

9:27 pm on Mar 29, 2007 (gmt 0)



Try the following:

<?php
session_start();
$newip = $_SERVER['REMOTE_ADDR'];
$currentID = array();
preg_match('/cat([0-9]+)/', $_SERVER['REQUEST_URI'], $currentID);
#
if (empty($_SESSION['customer_number']) ¦¦ empty($_SESSION['customer_number']) ¦¦ ($newip!= $_SESSION['ip']) ¦¦ ($_SESSION['destinationID']!= $currentID)){
echo 'Logged out.';
include "logout.php";
exit;
}
#
?>

Remember to replace the pipe characters!

cameraman

9:32 pm on Mar 29, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Way up where it says //process search, after:
$row = mysql_fetch_array($result);
add
echo $row['destinationID'];

to make sure you're getting it here. And just to make sure you know, $result can be set even though no rows match your query - $result will be FALSE if there's a syntax error in the query, but if the query is valid, a resource id will be returned to $result. Therefore, you also want to make sure:
$mysql_num_rows($result)!= 0

It looks to me the way your script is structured, an invalid customer_number/password will still set the first two session variables but the destination will be blank since no rows matched the query.

Also make sure you clear your session cookie before testing to see if you can gain unauthorized access to the page, unless you know that you've executed logout and that it is unsetting the session variables.

Awful newbie

9:38 pm on Mar 29, 2007 (gmt 0)

10+ Year Member



I will try, by the way: there is no cookie here?

[edited by: Awful_newbie at 9:40 pm (utc) on Mar. 29, 2007]

Awful newbie

9:51 pm on Mar 29, 2007 (gmt 0)

10+ Year Member



Sorry, I didn't quite get you, but now it seems that the protection maybe works, but now the processing script hangs, I don't know where to put this:
$mysql_num_rows($result)!= 0

as you mentioned. I putted it in

if( $result ) {
$row = mysql_fetch_array($result);
HERE---> $mysql_num_rows($result)!= 0;

echo $row['destinationID'];

But that was obviously wrong.

cameraman

9:58 pm on Mar 29, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Sorry, I was being lazy. You could change:
//process search
.
.
if( $result ) {

to:
if( $result && (mysql_num_rows($result)!= 0)) {

Awful newbie

1:15 am on Mar 30, 2007 (gmt 0)

10+ Year Member



Process still hangs, but the correct destinationID are displayed on the hanging process page, but no redirect are initiated.
(The protection now appear to work, but the login hangs)

..
//process search
$sql="SELECT destinationID FROM $tbl_name WHERE customer_number='$customer_number' AND customer_pass='$customer_pass'";
$result=mysql_query($sql);

if ($result && (mysql_num_rows($result)!= 0)) {
$row = mysql_fetch_array($result);
echo $row['destinationID'];

}

..here coms the redirect...

[edited by: Awful_newbie at 1:16 am (utc) on Mar. 30, 2007]

Awful newbie

7:17 am on Mar 30, 2007 (gmt 0)

10+ Year Member



Is it something wrong with the SQL query, or perhaps the register sessions is placed wrong in the process script? I am now able to protect the target files with session restriction, but now the process script (this script) hangs and displays the destinationID. It won't forward the user. I need help.

I have moved the session data at the beginning of the script:

<?php
session_start();

//register user session
$_SESSION['customer_number'] = "$customer_number";
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['destinationID'] = $row['destinationID'];

//and after login details and connection details the sql comes:

//process search
$sql="SELECT destinationID FROM $tbl_name WHERE customer_number='$customer_number' AND customer_pass='$customer_pass'";
$result=mysql_query($sql);

if ($result && (mysql_num_rows($result)!= 0)) {
$row = mysql_fetch_array($result);
echo $row['destinationID'];

}

//and finally the redirect comes:

switch($row['destinationID']) {
case '10':
header("location:http://www.example.com/customers/cat10/index.php");
break;
case '20':
header("location:http://www.example.com/customers/cat20/index.php");
break;

//etc... until:
default:
printf("Wrong customer number or customer pass<br>\n<a href='javascript:history.go(-1)'>back</a>");
}

?>

cameraman

10:14 am on Mar 30, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Now that you've verified that destinationID is getting pulled from the table you can remove that echo - that will interfere with header().

Any time you're having problems with a script and need to debug it, you should put:
error_reporting(E_ALL);
at the top of the script (as whoisgregg suggested), then remove it once you're finished debugging. That tells php to tell you all errors & warnings and can give you very helpful information. The next helpful thing to do is to echo your variables so you know you're getting what you expect. Once you've verified a particular variable, remove the echo and move on down to the next possible problem.

Awful newbie

10:27 am on Mar 30, 2007 (gmt 0)

10+ Year Member



Thanks, I did as you said. The sad thing is that I don't get any error output from it. But after removing the echo I get frowarded upon correct user input!

But now I don't get access to the destination url. Something in the session restriction prevent access, despite correct processing. I only get the echoed output.

This is the code in the top of the protcted page:

<?php
session_start();
error_reporting(E_ALL);
$newip = $_SERVER['REMOTE_ADDR'];
$currentID = array();
preg_match('/cat([0-9]+)/', $_SERVER['REQUEST_URI'], $currentID);

if (empty($_SESSION['customer_number']) ¦¦ empty($_SESSION['customer_number']) ¦¦ ($newip!= $_SESSION['ip']) ¦¦ ($_SESSION['destinationID']!= $currentID)){
echo 'You are not logged in.';
include "logout.php";
exit;
}

?>

<html><head><title>success</title></head><body>
<b>The page content comes here.</b></body></html>

cameraman

5:22 pm on Mar 30, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You dropped a line out of whoisgregg's code snippet - after the preg_match line, add this back in:
$currentID = (isset($currentID))? $currentID[1] : null;

Awful newbie

6:49 pm on Mar 30, 2007 (gmt 0)

10+ Year Member



HOLY MACARONI!

Thank you all! It finally works! I am in deep debt to you, please recieve a tanker with digital ale from me :-)))

whoisgregg

12:43 pm on Apr 2, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Glad to see you got it sorted. :)

System

10:27 am on Apr 3, 2007 (gmt 0)

redhat



The following message was cut out to new thread by jatar_k. New thread at: php/3300982.htm [webmasterworld.com]
9:42 am on April 3, 2007 (est -4)