ianstrand Posted May 22, 2022 Share Posted May 22, 2022 Hello! I'm trying to update an old login form that I created that stores the website's admin username and password in a database, and I am feeling a little silly but can't figure out why this does not work anymore. The website is successfully pulling other values from the MySQL database, and so I do not think that that is the cause for the issue, but I am getting an empty array value when I try to check for errors: Array ( [0] => 00000 [1] => [2] => ). The layout for the table looks like what I am adding below: username password example_username example_password The PHP version for the site is 7.4. I am almost 100% sure that the error is not coming from any of the includes files, because everything else is working on the site. I think that there likely has been an update or something that I am misunderstanding that is affecting the below page code: <?php define( 'TITLE', 'Log In' ); include '../includes/connection.php'; include 'includes/header.php'; include 'includes/nav.php'; ?> <!-- Begin page content --> <main class="flex-shrink-0"> <div class="container"> <div style="padding-top: 10%;"> <?php // Attempt Log In $submit = $_POST[ 'submit' ]; if ( $submit == 'Log In' ) { $username = $_POST[ 'username' ]; $password = sha1( $_POST[ 'password' ] ); // $username = 'username'; // $password = 'password'; // echo "Your username is ".$username.' and your password is '.$password; $sql = $dbh->prepare( "select username from fr_admin where username = ? and password = ?" ); $sql->bindValue( 1, $username, PDO::PARAM_STR ); $sql->bindValue( 2, $password, PDO::PARAM_STR ); $sql->execute(); print_r($sql->errorInfo()); $sqlresults = $sql->fetch(); $uname = $sqlresults[ 'username' ]; if ( $uname == $username ) { $_SESSION[ 'admin' ] = 'authorized'; $_SESSION[ 'username' ] = $username; } else { echo '<p class="text-danger"><strong>There was a problem logging in. Please try again!</strong></p>'; } } // Display for logged out users if ( $_SESSION[ 'admin' ] != 'authorized' ) { ?> <h3 class="mt-3 mb-4">Please log in to add a film review.</h3> <!-- Log In Form --> <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post" class="pb-5"> <div class="form-group"> <label for="username" class="pt-3">Username</label> <input type="text" class="form-control" name="username" id="username" aria-describedby="username" required placeholder="Enter Username"> </div> <div class="form-group pb-3"> <label for="password" class="pt-3">Password</label> <input type="password" class="form-control" name="password" id="password" aria-describedby="password" required placeholder="Enter Password"> </div> <!--<input type="submit" name="submit" value="Log In">--> <button class="btn btn-primary" type="submit" name="submit" value="Log In">Log In</button> </form> <?php } else { // Successful Log In echo '<p><strong class="text-success">Welcome, ' . $_SESSION[ 'username' ] . '.</strong>'; echo '  —  <a href="logout.php">Log Out</a></p><h3 class="mt-3 mb-5">Add a film review below.</h3>'; // Attempt to add film review if ( $_SERVER[ 'HTTP_REFERER' ] == 'https://strandian.com/SDCCD/webd167/finalproject/admin/index.php' || $_SERVER[ 'HTTP_REFERER' ] == 'https://strandian.com/SDCCD/webd167/finalproject/admin/index.php' ) { if ( $submit == 'Add Film Review' ) { $title = $_POST[ 'title' ]; $content = $_POST[ 'content' ]; $inssql = $dbh->prepare( "insert into fr_films (filmtitle,filmreview) values (?,?)" ); $inssql->bindValue( 1, $title, PDO::PARAM_STR ); $inssql->bindValue( 2, $content, PDO::PARAM_STR ); $inssql->execute(); $lastid = $dbh->lastInsertId(); $newpicname = $lastid . '.jpg'; $bool = move_uploaded_file( $_FILES[ 'photo' ][ 'tmp_name' ], '../images/uploads/' . $newpicname ); if ( $bool ) { echo '<p class="text-success"><strong>   Record inserted and picture uploaded!</strong></p>'; } else { echo '<p class="text-danger"><strong> There was a problem adding your review!</strong></p>'; } } } ?> <!-- Form to Add Film Review --> <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post" enctype="multipart/form-data" class="pb-5"> <div class="form-group"> <label for="title" class="pt-3">Title</label> <input type="text" class="form-control" name="title" id="title" aria-describedby="title" required placeholder="Enter Film Title"> </div> <div class="form-group pb-4"> <label for="content" class="pt-3">Content</label> <textarea name="content" class="form-control" id="content" rows="4" required placeholder="Enter Review Content"></textarea> </div> <div class="custom-file mb-3"> <input type="file" name="photo" class="custom-file-input" id="photo" required accept=".jpg, .jpeg"> <label class="custom-file-label" for="photo">Add a photo (jpeg)</label> </div> <!--<input type="submit" name="submit" value="Add Film Review" class="mt-4">--> <button class="btn btn-primary mt-4" type="submit" name="submit" value="Add Film Review">Add Film Review</button> </form> <?php } ?> </div> </div> </main> <!-- Script to display filename for <input type="file"> in Add Film Review table --> <script> $('#photo').on('change',function(){ //get the file name var fileName = $(this).val(); //replace the "Choose a file" label $(this).next('.custom-file-label').html(fileName); }) </script> <?php include '../includes/footer.php'; ?> I really appreciate anyone taking the time to help me with this! Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/ Share on other sites More sharing options...
ginerjm Posted May 22, 2022 Share Posted May 22, 2022 Did you check if you got a row from your query? Do you have error checking enabled? // Attempt Log In $submit = $_POST[ 'submit' ]; if ( $submit == 'Log In' ) { $username = $_POST[ 'username' ]; $password = sha1( $_POST[ 'password' ] ); // echo "Your username is ".$username.' and your password is '.$password; $sql = $dbh->prepare( "select username from fr_admin where username = ? and password = ?" ); $sql->bindValue( 1, $username, PDO::PARAM_STR ); $sql->bindValue( 2, $password, PDO::PARAM_STR ); IF (!$sql->execute()) { print_r($sql->errorInfo()); EXIT(); } // execute ran. // did we get a row back? if ($sqlresults = $sql->fetch()) { $uname = $sqlresults[ 'username' ]; if ($uname == $username) // WHY THIS TEST??? YOU JUST ASSIGNED THE VALUE SO IT HAS TO BE == { $_SESSION[ 'admin' ] = 'authorized'; $_SESSION[ 'username' ] = $username; } else { echo '<p class="text-danger"><strong>There was a problem logging in. Please try again!</strong></p>'; } } This is the only part I think that we are interested in... Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/#findComment-1596549 Share on other sites More sharing options...
Barand Posted May 22, 2022 Share Posted May 22, 2022 It looks like you expect $sql->fetch() to return an associative array. It puts the resuts into bound variables Quote (PHP 5, PHP 7, PHP mysqli_stmt::fetch -- mysqli_stmt_fetch — Fetch results from a prepared statement into the bound variables Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/#findComment-1596553 Share on other sites More sharing options...
ianstrand Posted May 22, 2022 Author Share Posted May 22, 2022 (edited) Thank you so much for your help - I am very grateful! I just checked on all of your questions and information, and for some reason my error reporting wasn't displaying correctly before. I am getting the error Notice: Trying to access array offset on value of type bool in /home/dh_9ugzbs/strand/SDCCD/webd167/finalproject/admin/index.php on line 28, which I think is what Barand just posted about: 2 hours ago, ianstrand said: $sqlresults = $sql->fetch(); $uname = $sqlresults[ 'username' ]; I was concerned that the query was not getting a row, but when I test this in phpMyAdmin, that seems to be working. I found this tutorial at https://www.tutorialrepublic.com/php-tutorial/php-mysql-login-system.php - should I change the formatting of the code to be more like this? Thank you again! Edited May 22, 2022 by ianstrand Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/#findComment-1596555 Share on other sites More sharing options...
Barand Posted May 22, 2022 Share Posted May 22, 2022 Before you fetch() us this .... https://www.php.net/manual/en/mysqli-stmt.bind-result.php Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/#findComment-1596556 Share on other sites More sharing options...
ianstrand Posted May 22, 2022 Author Share Posted May 22, 2022 Thank you so much! I was having some trouble getting this to work, I think because this is a PDO connection. Would fetchAll or creating a while loop be a good alternative for this? https://www.php.net/manual/en/pdostatement.fetchall.php I think that there is possibly a secondary issue with the table, because when I try to print any array I do not get any values (unlike with the other tables in the database). Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/#findComment-1596557 Share on other sites More sharing options...
Solution mac_gyver Posted May 22, 2022 Solution Share Posted May 22, 2022 (edited) @Barand, the OP is using PDO. bindValue(), PDO::PARAM_STR, and errorInfo() are all PDO elements. the error you are getting, assuming that php's error_reporting is set to E_ALL, means that the query didn't match a row. you need to test when you fetch the row if anything was fetched. if a row was fetched, it means that the WHERE clause was true and there's no need to test in the current php code if the form username matched the fetched username. however, if no row was fetched, this indicates that the WHERE clause was false. that's the condition where you would setup the login failure message. as to why the query isn't matching a row, and isn't producing an error, are you sure the username/password that you used was correct? when you executed the query directly in phpmyadmin, did it contain the sha1() password hash or did it directly have the password in it? when you make the database connection are you - setting the character set to match your database tables? setting the error mode to exceptions setting emulated prepared queries to false setting the default fetch mode to assoc as to the link you posted, don't take a backward step and use the mysqli extension. the PDO extension is the best choice, though you can simplify how you are using it, and whatever is causing the current code to not match a row will still be a problem with a different database extension. btw - you should be using php's password_hash() and password_verify(). the simple sha... hashing functions where never intended for security purposes. you should also only store the user id (autoincrement primary index) in the session variable to identify who the logged in user is. you should query on each page request to get any other user information, such as the username or user role/permissions. this insures that any changes made to these values will take affect on the very next page request. Edited May 22, 2022 by mac_gyver Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/#findComment-1596558 Share on other sites More sharing options...
mac_gyver Posted May 22, 2022 Share Posted May 22, 2022 4 minutes ago, ianstrand said: fetchAll or creating a while loop be a good alternative no. this query should match, at most, one row (the username should be defined as a unique index.) Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/#findComment-1596559 Share on other sites More sharing options...
Barand Posted May 22, 2022 Share Posted May 22, 2022 7 minutes ago, mac_gyver said: @Barand, the OP is using PDO. bindValue(), PDO::PARAM_STR, and errorInfo() are all PDO elements. Oops!. Sorry about that. I am so used to passing an array to the execute() method that I forget PDO also has parameter binding option. Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/#findComment-1596560 Share on other sites More sharing options...
ginerjm Posted May 22, 2022 Share Posted May 22, 2022 Because I saw the binds I didn't even notice that he was using PDO. Surprised!! Yes - you are right. The array method is so much easier and using a list to capture the query results is even easier than the bind. Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/#findComment-1596561 Share on other sites More sharing options...
ianstrand Posted May 23, 2022 Author Share Posted May 23, 2022 Hi again, Apologies for the delayed response - I can't thank you enough for your help! This is a little embarrassing but you were exactly right, mac_gyver; I was using the wrong password. I was able to get this to work, and I will definitely implement your security recommendations for this login / site. Thank you again everybody for your help in solving this!! Quote Link to comment https://forums.phpfreaks.com/topic/314825-login-form-username-password-values/#findComment-1596592 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.