#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2014
    Location
    AR, USA
    Posts
    12
    Rep Power
    0

    Problem with login script and pwd salt


    Using the guide I found in this forum: program basic secure login system, I set up a successful registration page. I'm having trouble with logging in, though.

    I have modified the code for mySQLi, and I might have a mistake somewhere. The problem appears to be that the salt is not returning from the table. In my efforts to dicover the problem, I have removed some of the security built into the original code--hashing only once, for example. Here's the current login portion of the page.

    PHP Code:
    $row $stmt->fetch();
    $pwdCheck clean($_POST['tfPassword']);
    if(
    $row){
       print(
    "found row to check.<br />");
      
    $s $row['salt'];
      
    $pwdCheck hash('sha256',$pwdCheck.$s);
      if(
    $pwdCheck === $row['password']) $LoginSuccess=TRUE;
    }
    if(
    $LoginSuccess){
      unset(
    $row['salt']);
      unset(
    $row['password']);
      
    $_SESSION['user'] = $row;
      
    header("Location: private.php");
      die(
    "Redirecting to: private.php");
    }
    else{
      print(
    "Login Failed. ");
      
    $submittedUsername htmlentities($_POST['tfUsername'], ENT_QUOTES'UTF-8');

    When I kept getting the "Login Failed" message, I verified that the password was getting hashed before adding to the table, and I verified that the salt was added to the table. Then, I added code to put the hashed pwd and the salt in the username field so that I could see what was being checked. The salt was returning an empty string!

    Is there something someone else sees that might be keeping me from getting the salt from my table while simultaneously getting the username and password successfully?
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2014
    Location
    AR, USA
    Posts
    12
    Rep Power
    0
    I made a change in the first part of the code that doesn't appear in the original post, but I cannot edit the post to show the change. So, here's the current, complete code for that page.

    PHP Code:
    $submittedUsername="";

    if(!empty(
    $_POST)){
      
    $u=clean($_POST["tfUsername"]);
      
    $stmt $conn->prepare("SELECT id, username, password, salt, email FROM users WHERE username= ? ");
      
    $stmt->bind_param('s',$u);
      
    $stmt->execute();
      
    $res $stmt->get_result();
      
    $row $res->fetch_assoc();

      
    $LoginSuccess FALSE;
      if(
    $row){
        
    $s=$row['salt'];
        
    $p=clean($_POST['tfPassword']).$s;
        
    $pwdCheck hash('sha256',$p);
        if(
    $pwdCheck == $row['password']) $LoginSuccess=TRUE;
      }
      if(
    $LoginSuccess){
        print(
    "Login Successful.");
        unset(
    $row['salt']);
        unset(
    $row['password']);
        
    $_SESSION['user'] = $row;
        
    header("Location: private.php");
        die(
    "Redirecting to: private.php");
      }
      else{
        print(
    "Login Failed.");
        
    $submittedUsername htmlentities($_POST['tfUsername'], ENT_QUOTES'UTF-8');
      }

  4. #3
  5. Not An Expert
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2015
    Posts
    404
    Rep Power
    3
    Hey there!

    The inability to edit posts is an anti-spam measure put in place on our forums. I've manually upgraded your user privileges so you should be able to edit your own posts in the future. Typically these privileges unlock automatically, but I can tell that you're not a spammer so I decided to just manually upgrade you early.

    If you want to edit a post that you just made, you may need to refresh the page to get the edit button to show up. It will be in the bottom right corner of your post.

    Well...not exactly the corner, but the bottom right side

    There is also a time-limit on editing of posts. Currently that time limit is 20 days - so after 20 days has passed, your posts will no longer be available for editing. That's also some spam protection. But if you need very very old posts edited feel free to send me an email at markr@imninjas.com with your requested changes and a link to the post and I'd be happy to help.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Apr 2009
    Posts
    2,232
    Rep Power
    1296
    If your select query is returning an empty value for the salt field, then you should be looking at the section of code that inserts/updates that value in the db to find out why it's empty.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2014
    Location
    AR, USA
    Posts
    12
    Rep Power
    0
    Originally Posted by markroberts
    I can tell that you're not a spammer so I decided to just manually upgrade you early.
    Thank you!
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2014
    Location
    AR, USA
    Posts
    12
    Rep Power
    0
    Originally Posted by FishMonger
    If your select query is returning an empty value for the salt field, then you should be looking at the section of code that inserts/updates that value in the db to find out why it's empty.
    I can see the 'users' table has my entry in it to verify that there is data in the table. I think the problem lies with my SELECT statement I parameterized. I wrapped all of those statements in if clauses to output errors, but now I see no errors, and the "login failed" message doesn't appear. But the page doesn't go anywhere. I'm really close to just scrapping the whole thing and starting over, I think.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2014
    Location
    AR, USA
    Posts
    12
    Rep Power
    0
    OK, good news on the login front. The login page is working. Below is the final code with with parameterized query and results. (The only thing left to fix is carrying the information to the next session. The private.php page doesn't display the user's name like I want it to.)

    PHP Code:
    <?php
    require("common.php");

    $submittedUsername="";

    if(!empty(
    $_POST)){
      
    $u=clean($_POST["tfUsername"]);
      if(!(
    $stmt $conn->prepare("SELECT id, firstName, lastName, username, password, salt, email FROM users WHERE username= ? "))) echo "Prepare Failed (".$conn->errno.") ".$conn->error;
      if(!
    $stmt->bind_param('s',$u)) echo "Binding failed: (".$stmt->errno.") ".$stmt->error;
      if(!
    $stmt->execute()) echo "Execution failed: (".$stmt->errno.") ".$stmt->error;
      if(!
    $stmt->bind_result($i,$f,$l,$u,$p,$s,$e)) echo "Binding output parameters failed: (".$stmt->errno.") ".$stmt->error;
      if(
    $row $stmt->fetch()){
        
    $pwdCheck clean($_POST['tfPassword']).$s;
        
    $LoginSuccess FALSE;
        
    $pwdCheck hash('sha256',$pwdCheck);
        if(
    $pwdCheck == $p$LoginSuccess=TRUE;
      }
      if(
    $LoginSuccess){
        unset(
    $row['salt']);
        unset(
    $row['password']);
        
    $_SESSION['user'] = $row;
        
    header("Location: private.php");
        die(
    "Redirecting to: private.php");
      }
      else{
        print(
    "Login Failed.");
        
    $submittedUsername htmlentities($_POST['tfUsername'], ENT_QUOTES'UTF-8');
      }
    }
    ?>
    Of course, I will do something different with those errors in production, but I wanted to just present them to myself if there was an issue.
  14. #8
  15. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2009
    Posts
    351
    Rep Power
    258
    Congrats on getting the login working! So is this problem completely solved then?
    - The Wise Guy
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2014
    Location
    AR, USA
    Posts
    12
    Rep Power
    0
    Not quite. I am not getting the user's information to carry over into the next page using the session variable. I think this has to do with the way I'm getting the value for $row. Instead of values like the user's name or email address, I get 1's for most of what I call on the next page.
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Apr 2009
    Posts
    2,232
    Rep Power
    1296
    The only session var you're assigning in that code is:
    PHP Code:
    $_SESSION['user'] = $row
    $row is the return value (true or false) from your fetch statement. It is not the field value returned from the database.

    If you want the values that were fetched, then you need to use the bind vars $i,$f,$l,$u,$p,$s,$e to assign individual session vars.

    Comments on this post

    • jasotastic agrees
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Apr 2009
    Posts
    2,232
    Rep Power
    1296
    This is unrelated to your question, but you're making the same mistake that 90% of the php programmers that I've come across make and that is improper code formatting. Most php coders here and in some of the other forums I work with care more about using the php code tags (so that the code is colorized) than they do with code formatting/readability.
  22. #12
  23. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2009
    Posts
    351
    Rep Power
    258
    I think it's easier to just bind an associative array to the session variable. I changed your code around a bit to make it easier to read, and removed some extraneous errors that will probably never occur. The logic is, if MySQLi is able to prepare a query, it will execute successfully. If 1 row is returned and the password from that row matches the one posted, it indicates a successful login. Finally, if there is no redirect & die, then the user entered an incorrect username or password.
    PHP Code:
    <?php
    require('common.php');

    if (!empty(
    $_POST)) {
        
    $query 'SELECT id, firstName, lastName, username, password, salt, email 
            FROM users 
            WHERE username = ?'
    ;
        
    $stmt $conn->prepare($query);
        
    /* Uncomment this to test query
        if (!$stmt) {
            echo "Prepare Failed ({$conn->errno}) {$conn->error}"; 
        }
        */
        
    $stmt->bind_param('s'clean($_POST['tfUsername']));
        
    $stmt->execute();
        
    $result $stmt->get_result();

        if (
    $result->num_rows  === &&
            
    $row $result->fetch_assoc() &&
            
    $row['password'] === hash(
                
    'sha256'
                
    clean($_POST['tfPassword']) . $row['salt']
            )
        ) {
            unset(
    $row['password']);
            unset(
    $row['salt']);
            
    $_SESSION['user'] = $row;
            
    header("Location: private.php");
            die(
    "Redirecting to: private.php");
        }
        
    $stmt->close();
        echo 
    'Login Failed.';
        
    $submittedUsername htmlentities($_POST['tfUsername'], ENT_QUOTES'UTF-8');
    }
    I haven't done any PHP in a very long time, and I'm not sure if fetch_assoc() will return a reference to an assoc and actually not work correctly, or if this will work. If it doesn't work, we'll have to use a call_user_func sort-of-thing to achieve this.
    Last edited by s-p-n; April 10th, 2016 at 01:30 PM.
    - The Wise Guy
  24. #13
  25. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2014
    Location
    AR, USA
    Posts
    12
    Rep Power
    0
    Well, it's working now. Thank you all for your suggestions. The problem just seems to be that I wasn't setting the SESSION array pieces correctly. Thank you all for your help

IMN logo majestic logo threadwatch logo seochat tools logo