3

I have a registration form which allows users to create a username and password which is then stored in the database.

<?php
//values to be inserted in database table
//session_start();
include('connect.php');

//Fixed cost of 10 to fit server req
//Random salt to be added to the pass
$options = [
    'cost' => 10,
    'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
];

$email = $_POST['email'];
$password= password_hash($_POST['password'], PASSWORD_BCRYPT, $options);
$username= $_POST['username'];

$query = "INSERT INTO users (username, email, password) VALUES(?, ?, ?)";
$statement = $mysqli->prepare($query);

//bind parameters for markers, where (s = string, i = integer, d = double,  b = blob)
$statement->bind_param('sss', $username, $email, $password);

if($statement->execute()){
     print 'Success! ID of last inserted record is : ' .$statement->insert_id .'<br />'; 
}else{
     die('Error : ('. $mysqli->errno .') '. $mysqli->error);
}
$statement->close();
?>

And here is my script in which checks whether the users inputted username and password exist.

<?php
include 'connect.php';
if ( !isset($_POST['username'], $_POST['password']) ) {
    // Could not get the data that should have been sent.
    die ('Username and/or password does not exist!');
}
// Prepare our SQL 
if ($stmt = $mysqli->prepare('SELECT password FROM users WHERE username = ?')) {
    // Bind parameters (s = string, i = int, b = blob, etc), hash the password using the PHP password_hash function.
    $stmt->bind_param('s', $_POST['username']);
    $stmt->execute(); 
    $stmt->store_result(); 
    // Store the result so we can check if the account exists in the database.
    if ($stmt->num_rows > 0) {
        $stmt->bind_result($password);
        $stmt->fetch();      
        // Account exists, now we verify the password.
        if (password_verify($_POST['password'], $password)) {
            // Verification success! User has loggedin!
                        echo 'You have logged in!';
        } else {
            echo 'Incorrect username and/or password!';
        }
    } else {
        echo 'Incorrect username blar password!';
    }
    $stmt->close();
} else {
    echo 'Could not prepare statement!';
}
?> 

It is outputting Incorrect username and/or password, so I am assuming the problem is with the way I've hashed the passwords in the registration system or whether its simply not finding the details I'm looking for.

HTML Form:

<div class="logmod__heading">
          <span class="logmod__heading-subtitle">Enter your username and password <strong>to sign in</strong></span>
        </div> 
        <div class="logmod__form">
          <form accept-charset="utf-8" action="loggedIn.php" method='POST' class="simform">
            <div class="sminputs">
              <div class="input full">
                <label class="string optional" for="user-name">Username*</label>
                <input class="string optional" maxlength="255" id="user-email" placeholder="username" type="username" name='username' size="100" />
              </div>
            </div>
            <div class="sminputs">
              <div class="input full">
                <label class="string optional" for="user-pw">Password *</label>
                <input class="string optional" maxlength="255" id="user-pw" placeholder="Password" type="password" name='password' size="100" />
                                        <span class="hide-password">Show</span>
              </div>
            </div>
            <div class="simform__actions">
              <input class="sumbit" name="commit" type="submit" value="Log In" />
              <span class="simform__actions-sidetext"><a class="special" role="link" href="#">Forgot your password?<br>Click here</a></span>
            </div> 
          </form>
        </div> 
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
Small Legend
  • 733
  • 1
  • 6
  • 20
  • 1
    and the password column type and length are? don't say "50", or "59" or anything less than 60. Plus, check your HTML form which you didn't post. – Funk Forty Niner Sep 23 '15 at 13:55
  • `type="username"` use `type="text"` – Funk Forty Niner Sep 23 '15 at 13:59
  • I edited my code with the HTML – Small Legend Sep 23 '15 at 13:59
  • 1
    shamelessly marketing this answer of mine [here](http://stackoverflow.com/a/32556010) – Drew Sep 23 '15 at 14:00
  • Incorrect username and/or password! – Small Legend Sep 23 '15 at 14:01
  • 1
    Add error reporting to the top of your file(s) right after your opening PHP tag for example `execute();` to `if(!$stmt->execute()){trigger_error("there was an error....".$mysqli->error, E_USER_WARNING);}` - see if there's anything wrong somewhere. – Funk Forty Niner Sep 23 '15 at 14:02
  • already seen your post today @Drew, trying to figure out the problem with my own code. If I just change to your code it'll keep me awake at night knowing that mine was unresolved haha – Small Legend Sep 23 '15 at 14:02
  • I usually make the databases password field a `TEXT`, in case the length of the hash gets changed in the future. – Jay Blanchard Sep 23 '15 at 14:02
  • 1
    ok, if no one answers, I will re-do it with yours good luck – Drew Sep 23 '15 at 14:02
  • 1
    Look at what @Fred-ii- said here, check for errors. You're not checking for errors, so you don't know if the data is even *in* the database. – Jay Blanchard Sep 23 '15 at 14:04
  • The only problem I have with your answer @Drew is that you do not use prepared statements for your `DELETE` and `INSERT`. In any event, if you think your answer is the right one, mark *this* question as a duplicate. – Jay Blanchard Sep 23 '15 at 14:06
  • @Fred-ii- getting no errors, just displaying "Incorrect username and/or password! " – Small Legend Sep 23 '15 at 14:07
  • 1
    Ok. Next step. Are there any spaces (leading/trailing) in the username and/or password column(s)? – Funk Forty Niner Sep 23 '15 at 14:08
  • @JayBlanchard, you need to read the context of that answer over there. I had to fake a registration form, which was not the point of that question. The point of that question was the verify (in which case I **DID** use **prepared statements**). So I was going the extra mile in saying let's say you have someone registered, and let's shove some fake data in to prove it. But that was completely off topic on that question – Drew Sep 23 '15 at 14:08
  • @Fred-ii- I don't believe so, I had the login system working before but with SQL, which I was told is vulnerable to SQL injection and redundant now – Small Legend Sep 23 '15 at 14:12
  • I know @Drew, but it demonstrates some bad coding practices which we should strive to correct when we post answers, – Jay Blanchard Sep 23 '15 at 14:13
  • 2
    ok, in the future I will expand questions to do registration forms too, really make their eyes glaze over – Drew Sep 23 '15 at 14:14
  • 1
    Just thought I would chip in a quote from the manual __Caution__ _It is strongly recommended that you do not generate your own salt for this function. It will create a secure salt automatically for you if you do not specify one._ – RiggsFolly Sep 23 '15 at 14:14
  • 1
    correct Riggs, it is recommended, it is as future proof as we can get, and the salt is baked into the **hash** – Drew Sep 23 '15 at 14:15
  • 1
    and changing `type="username"` to `type="text"` didn't work as previously suggested? It doesn't seem that `type="username"` is a valid type. You're not using additional JS/Ajax here that you're not showing, are you? – Funk Forty Niner Sep 23 '15 at 14:16
  • Would you mind adding to your question, a row from your table containing one of your users – RiggsFolly Sep 23 '15 at 14:17
  • Yes it worked thank you @Fred-ii- I didn't save the html code when I altered it ha! I'll never learn, thank you! – Small Legend Sep 23 '15 at 14:18
  • Great and you're welcome. I posted my answer below. *Cheers* – Funk Forty Niner Sep 23 '15 at 14:19
  • when someone manually forces data into a row, with hard-coded data, to show that it exists, and that was not user-supplied data, all as a test to demonstrate that the data is there, do not twist that into saying it is subject to sql injection attacks, @JayBlanchard – Drew Sep 23 '15 at 14:23
  • I'm not twisting anything @Drew, I'm just trying to help. *Sorry* – Jay Blanchard Sep 23 '15 at 14:25
  • np. But it is like saying one cannot issue this statement: `insert into t1(col1) values(9);` – Drew Sep 23 '15 at 14:26
  • Not entirely true @Drew, but we'll just have to agree to disagree. Hell, I even *UV'd* your answer on the other thread. – Jay Blanchard Sep 23 '15 at 14:29
  • thank you for the upvote. should have. and `9` above is hard-coded too. Prepared stmt not needed – Drew Sep 23 '15 at 14:39
  • 1
    @SmallLegend We both got downvoted. Lovely, isn't it? I sense a reptile slithering about. – Funk Forty Niner Sep 23 '15 at 15:15
  • 3
    *Special thanks goes out to "Y.. know who" for downvoting us all, and deleting one of the answers* - Your Contribution Sucks, you know that. – Funk Forty Niner Sep 23 '15 at 15:46

1 Answers1

5

type="username" isn't a valid form element type.

Change that to type="text"

However, I did mention that earlier in comments:

type="username" use type="text" – Fred -ii- 20 mins ago

Comment link...

  • I did say "use" and not "try" ;-)

You may have thought that a "username" type was HTML5 syntax; it isn't.

To see the list of valid HTML5 input type, consult the following link:

Pulled from the W3.org page:

The input element is a multipurpose element for representing input controls. The details of the input element are described in the following sections:

  • input type=text
  • input type=password
  • input type=checkbox
  • input type=radio
  • input type=button
  • input type=submit
  • input type=reset
  • input type=file
  • input type=hidden
  • input type=image
  • input type=datetime NEW
  • input type=datetime-local NEW
  • input type=date NEW
  • input type=month NEW
  • input type=time NEW
  • input type=week NEW
  • input type=number NEW
  • input type=range NEW
  • input type=email NEW
  • input type=url NEW
  • input type=search NEW
  • input type=tel NEW
  • input type=color NEW

Sidenote about using varchar(60) for your password column, and pulled from the password_hash() manual:

PASSWORD_DEFAULT - Use the bcrypt algorithm (default as of PHP 5.5.0). Note that this constant is designed to change over time as new and stronger algorithms are added to PHP. For that reason, the length of the result from using this identifier can change over time. Therefore, it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice).

Community
  • 1
  • 1
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
  • Thank you @Fred-ii- I'd have been stuck on that for days – Small Legend Sep 23 '15 at 14:33
  • 1
    You're most welcome @SmallLegend and was glad to have been of help. I also made a few more edits to my answer, in order to improve it for future readers, oh and for yourself also ;-) *Cheers* – Funk Forty Niner Sep 23 '15 at 14:42
  • 1
    who and why the hell was my answer downvoted as was the question? *facepalm* - and ultimately insulted. No snakes allowed on Stack. If you're going to downvote for the fun of it, then get yourself a handgun and play Russian roulette. – Funk Forty Niner Sep 23 '15 at 15:14
  • Well, we all know where that last one came from; and it stinks worse than rotten eggs. – Funk Forty Niner Sep 23 '15 at 18:11
  • @Drew Thanks man. Yeah... bit of a spat earlier in another question and the little bastard started serial downvoting me. – Funk Forty Niner Sep 23 '15 at 20:15