views:

45

answers:

4

I'm trying to make a login page using php, but when I use header() to redirect to another page, my user/pass check on my database somehow fails. Am I doing something wrong?

Also, I know I'm missing security guards, I'm implementing in steps since I'm still rather new to PHP. But some tips and suggestions would be appreciated!

$dbc = mysqli_connect('localhost', 'root', 'admin', 'wamad')
or die("Error connecting to MySQL server.");

$query = "SELECT * FROM $table WHERE username = '$username' and password = '$password';";

$result = mysqli_query($dbc, $query)
    or die("Login error");

if(mysqli_num_rows($result) == 1){

header("Location:login_success.php");
}else{
    echo "Wrong username or password.";
}

echo mysqli_num_rows($result);
mysqli_close($dbc);
A: 

I'm not 100% positive what you're trying to do, but typically you need to kill the script after using the location header.

header('Location: login_success.php');
die();

Otherwise the script continues to run after setting the header.

mellowsoon
I'm trying to check if a user login attempt is valid or not. When I don't have the header() line, it works fine, but when it's included, it doesn't seem to check properly against my db. I print out the search query for user/pass and I get a 0 when that line's included.
thomast.sang
Oh and...killing the script didn't work either
thomast.sang
A: 
$query = "SELECT * FROM $table WHERE username = '$username' and password = '$password';";

I don't know but there some semi-colon in after password '$password';"; and before ". you should remove it.

mike
The semicolon is valid syntax.
mellowsoon
A: 

You don't need the semicolon. And I never used a die(); after sending a header and it always worked fine.

Are you sending some output to the browser before you're sending the header? If that is the case your header won't be set. Are you displaying PHP errors? Do you have an error log? Are there errors showing up?

Additionally, headers should always end with a linebreak, so send header ("Location: login_success.php\n");

Sotapanna
No, I don't output anything prior to sending a header. The issue is mainly with mysqli_num_row($result). When I include the header, it doesn't find my query, otherwise it works fine. Can you also explain why headers should always end with a linebreak?
thomast.sang
Linebreaks seperate the header fields. Do you get any error messages in the error_log?
Sotapanna
nvm on the error, I know what I was doing wrong...silly mistake. Thanks!
thomast.sang
A: 

I hope you didn't just post the root password to your local MySQL server on the interwebs ;) A few points:

  • Escape those inputs (I know, you said you'd get to it)
  • Don't rely on mysqli_num_rows
  • Always close your database connection.

php-code: user/password database check

$dbc = mysqli_connect('localhost', 'root', 'admin', 'wamad');
if (!$dbc) {
    echo "Error connecting to MySQL server.";
    return;
}

//Escape these dangerous inputs... you said you were getting around to it.
$username=mysqli_real_escape_string($dbc,$_REQUET["username"];
$password=mysqli_real_escape_string($dbc,$_REQUET["password"];
$valid=false;

//Should avoid selecting * for performance and you never read it anyway
$result=mysqli_query($dbc,
    "SELECT username FROM my_security_table ".
    "WHERE username = '$username' and password = '$password'");

//The following should only display with an SQL error (ie. bad query)
if ($result===false) {
    echo "Unable to excute SQL on MySQL server.";
    return;
}

// mysqli_num_rows: Will only return the correct number if you're using 
//   buffered results, or you've read all the rows - not ideal.

//If we get a row, the user must be valid (could make further checks here)
if ($row=mysqli_fetch_array($result)) {
    $valid=true;
}
//Close the connection no matter what!
mysqli_close($dbc);

if ($valid) {
    header("Location:login_success.php");
} else {
    echo "Wrong username or password.";
}
Rudu