I need to redirect users to two (2) different pages based on the roles given to them in the database. Only the email and password is submitted on the login page. I have to fetch the role from the database which looks like this:

       Email    |   Password   |   UserType
  aa@me.com       xxxxxx       System User
  bb@me.com       xxxxxx       Administrator

And here is what I have done so far:

<?php
session_start();
error_reporting(0);
include('includes/dbconnection.php');

if(isset($_POST['login']))
  {
    $email=$_POST['email'];
    $password=md5($_POST['password']);
    $query=mysqli_query($con,"select ID from gts_users where  Email='$email' && Password='$password' ");
$ret=mysqli_fetch_array($query);
$count=mysqli_num_rows($query);
if($ret==1){
$_SESSION['detsuid']=array(
'Email'=>$ret['email'],
'Password'=>$ret['password'],
'UserType'=>$ret['role']
);

$role=$_SESSION['detsuid']['ID'];
switch($role){
 case 'System User':
 header('location: dashboard.php');
 break;
 case 'Administrator':
 header('location: admin/index.html');
 break;
 }
 }else{
echo "<script type='text/javascript'>alert('Wrong email and password combination');
</script>";
}
}
?> <form action="" method="post"> <input type="email" placeholder="E-mail" name="email"> <input type="password" name="password" placeholder=" Password"> <button type="submit" value="login" name="login">Login</button> </form>

Recommended Answers

All 19 Replies

Looks good to me. Good to see you try to cover the condition when there is no user role. But maybe you didn't need that line 29 else.

Why not use default ? Read how at https://www.w3schools.com/php/php_switch.asp

Hi rproffitt,

I tried removing the else but still can't direct me to either pages, the page is only refreshing that's all.

Thank you.

@Speed, I read your top post and couldn't find any problem statement. So my read was just to look over the logic and wonder about why the else statement. So my reply covers only that as I could not guess what issues you had since those were not shared or I missed it.

Since the switch didn't appear to work, be sure to echo or log the variables used after say line 20 so you can debug it.

PS. There's another problem if the above code is what you use. The name and passwords appear to be "in plain text" in some database. This is a bad idea that was taught for years and folk are having to unlearn that. There are many articles about that issue. Here's a few from google: https://www.google.com/search?q=Never+store+passwords+in+your+database&gl=US

@rproffitt, the password is encrypted with MD5, besides this project is for learing purposes. I will do my best to learn newer and safer ways of storing whatever data in the database, all in all, thank you for your contributions.

That's good but encryption is one of the steps. Needs to be salted as well. This is covered widely.

I can't tell if you solved the above. My apologies but I didn't find you writing it was broken in the top post. (no problem statement.)

I haven't figured out where the proble is. I posted it here with a view that someone may help where I went wrong.

To find out where it went wrong, echo or log those variables and results as your code runs. I run into a lot of programmers that forget they can echo or log to see why their code isn't working. As there is no error message shared and we don't know the database and more, more debugging information could crack this case.

For example, are you sure that $role matches or not?

There are two reasons this code might not do what you expect.

  1. The switch/case test fails in some way. What if the string you have in the code is not the string that is in the database?
    You won't know unless you debug this code.
  2. The header() function isn't working. This one is a bit easier to test. Hardcode it one way and then the other. Does it work? Then the issue is likely to be in the switch/case code. Which I can't test for you as I do not have your database or system.
<?php
ob_start();
session_start();
error_reporting(0);
// include('includes/dbconnection.php');
$connection = mysqli_connect("localhost", "username", "password", "database");
if(mysqli_connect_errno()) {
    echo "Failed to connect MYSQL: ".mysqli_connect_error();
}
  if(isset($_POST['login']) && $_POST['login'] == "login")
  {
    $email=$_POST['email'];
    $password=md5($_POST['password']);
    $sql = "SELECT * FROM gts_users WHERE email =".mysqli_real_escape_string($connection, $email)." AND password =".mysqli_real_escape_string($Connection, $password);
    $query=mysqli_query($connection, $sql);
    $count=mysqli_num_rows($query);
    if($count > 0){
        $ret=mysqli_fetch_array($query);
        $_SESSION['detsuid']=array(
        'Email'=> $ret['email'],
        'Password'=> $ret['password'],
        'UserType'=> $ret['role']
        );
        $role=$_SESSION['detsuid']['ID'];
        switch($role){
          case 'System User':
          header('location: dashboard.php');
          break;
          case 'Administrator':
          header('location: admin/index.html');
          break;
          default:
          // Code to be executed if n is different from all Roles
          header('location: user/index.html');
        }
    } else { ?>
          <script type='text/javascript'>
            alert('Wrong email and password combination');
          </script>";
    <?php
    }
  }
?> 
<form action="" method="post">
  <input type="email" placeholder="E-mail" name="email">
  <input type="password" name="password" placeholder=" Password">
  <input type="submit" value="login" name="login">
</form>
<?php ob_end_clean(); ?>
commented: I apologise for the pepper below. Look at lines 27 and 30. Intentionally break them so you know header() works. +15

I don't see any log or debug statements in that code. Is it working now? Why?

@harjinder007, the code above is only taking me to the default page.
I appreciate and value your contribution.

Above I wrote about adding debug code and testing to see if your header() lines of code work. I can not do this for you as I do not have your database, web server etc. But you are there so you have to do the debug.

Member Avatar for Mark_k

Hey,

OK so, few things:
1 - Just stop with md5. It's completely useless. You might as well just store in plain text if this really is just for learning. Google what rainbow tables are, and further to that, watch this https://youtu.be/7U-RbOKanYs?t=249
2 - Start using PDO and prepare your statements. I see later on you started using mysqli_real_escape_string and that's great, but again, just start using PDO.
3 - var_dump() and var_export() are your friends. Use those to see what you have inside of $ret;
4 - If this just for learning purposes, I'm not sure why you'd turn off all errors with error_reporting(0). See https://www.php.net/manual/en/function.error-reporting.php#refsect1-function.error-reporting-examples
5 - At the very top of this you show that you have a table with the columns Email, Password and UserType. The one thing in particular to note here is that you don't have a column called "role", but you keep trying to access $ret['role'] as if you do have that column. So check that.
6 - Further to that, you have this code:

$ret=mysqli_fetch_array($query);
$_SESSION['detsuid']=array(
    'Email'=> $ret['email'],
    'Password'=> $ret['password'],
    'UserType'=> $ret['role']
);
$role=$_SESSION['detsuid']['ID'];

What is ID? I don't see ID being defined anywhere and it's definitely not where the actual role or "UserType" is going to be. It should just be at $_SESSION['detsuid']['UserType'] and that's only if you change the line that has 'UserType' => $ret['role'] to 'UserType' => $ret['UserType'] becuase that's what the actual column name is from what I can tell. Again, do a var_dump($ret) to see what you have.

7 - You may wanna consider exit; after your header('Location') redirects. See https://www.php.net/manual/en/function.header.php#refsect1-function.header-parameters

8 - Don't store the password in the session. Never do that. Remove the line 'Password' => $ret['password']. You should even reduce your query from * which means give me everything in that row to just Email, UserType. That's all you need from that table.

Hope that helps.

Just stop with md5. It's completely useless.

Not that you're doing it, but MD5() with both a salt and a pepper are a little better because they make rainbow tables useless, but I would use password_hash() because not only is it more secure, but it isn't any harder to use.

Member Avatar for Mark_k

Not that you're doing it, but MD5() with both a salt and a pepper are a little better because they make rainbow tables useless, but I would use password_hash() because not only is it more secure, but it isn't any harder to use.

A salted MD5 is not even a little better. It 100% will not hold up to Hashcat. Again, watch the video I posted in point 1.

Do use pasword_hash()! [thumbsup emoji]

"select ID from gts_users where  Email='$email' && Password='$password' "

1) Your select statement is incorrect as you are trying to call just the ID, so all it returns is the ID, ot the Email which is required to search your other table to return the UserType. (Note to poster - try and refrain from using capital letters in your naming of tables and fields. Also try and use underscores when using 2 or more words for a field or table i.e. UserType - rather do user_type)

$_SESSION['detsuid']=array(
'Email'=>$ret['email'],
'Password'=>$ret['password'],
'UserType'=>$ret['role']

You have then tied $ret to your actual data returned but the field names is not recognised. email should be 'Email', password should be 'Password' and lastly role should be 'UserType' Seeing that no record has been returned because of the incorrect "select statement", you are returning an empty row, there are no error checking in place to say - "Take me there if no row is returned", your if statement only relies on a true returned row.

The below should do the trick -

if(isset($_POST['login']))
  {
    $email=$_POST['Email']; //Capital E here as per your table...
    $password=md5($_POST['Password']);Capital P, also bad practise here...
    $query=mysqli_query($con,"SELECT * FROM gts_users WHERE  Email=" . '$email' . " AND Password=" . '$password' . ""); //Select all fields and not just ID. ALSO, use AND and not &&, also note the dots as you are escaping your statement to enter the strings called...
$ret=mysqli_fetch_array($query);
$count=mysqli_num_rows($query);
if($ret==1){
$_SESSION['detsuid']=array(
'Email'=>$ret['Email'],
'Password'=>$ret['Password'],
'UserType'=>$ret['UserType']
);
} else {
    echo "No row returned, i have a problem in my selecting of data..."
} //This is a simple check, please make use of more advanced error returned messages...

Thank you for your posts, I managed to work around the problem of course with your help.
I have started working with PDO for security as well as hashing in replacement of crackable MD5.
Will keep on applying your suggestions as I get along with learning HTML, PHP, Java Script, and MYSQL.
All in all, you guys are wonderful.
Thank you once more.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.