0

My previous attempt at asking ended up being flagged as already solved. It linked to this post. After copying the code line for line

$db = new PDO('sqlite:practice.sqlite');
$db->setAttribute( PDO::AFTER_ERRMODE, PDO::ERRMODE_EXCEPTION );

$name = '';
if(isset($_POST['name'])) {
  $name = $_POST['name'];
}
$password = '';
if(isset($_POST['password'])) {
  $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
}

$query = $db->prepare("SELECT EXISTS (SELECT * FROM users WHERE name = :name AND password = :password)");
$query->execute(array(':name' => $name, ':password' => $password));
$result = $query->fetchAll();

if(count($result) > 0) {
  echo 'exists';
} else {
  echo 'doesnt exist';
}

This code always echoes out "exists" whether the user exists or not. I have also attempted this with only the user name, same result. I have, as well, attempted this with only the SELECT * FROM users;, without SELECT EXISTS(...), which changed nothing.

In the original post there was an answer which offered two possible solutions. Both of these had the same result. At this point I have read about every single possible way of doing this, on and off stackoverflow. Please help me understand what I am missing here. Every single resource I've studied on this problem doesn't work.

a.anev
  • 125
  • 1
  • 4
  • 11
  • 2
    Although you shouldn't be using password as one of the search criteria, if you do use it - you need to bind the value you are searching for. Currently you only bind the name. – Nigel Ren Jun 05 '22 at 16:28
  • 2
    You say you've tried this a few different ways, but some of the things you're trying are definitely not helping. Adding `select exists(...)` will mean you always get a result set, containing a boolean true/false. Adding the password to the where clause will likely mean an error, since the parameter count no longer matches the query. I can't see any obvious reasons this would always show "exists", but take a step back and stop throwing everything you can think of at the problem. Reproduce the problem using a **minimal** example, not with several half-finished attempts still in the code. – iainn Jun 05 '22 at 16:34
  • @iainn I have removed select exists(...) and now it only returns "doesnt exist" for every query I sent it. I also removed the password from the query and removed from the execute() array, same result. The reason I have the password there is because I wanna log in the user. And I figure its better to get it done with one query rather than pinging the db for the username first then checking if the password attached to said username is correct. I'm guessing that's not best practice though. – a.anev Jun 05 '22 at 16:57
  • @NigelRen Yes, good catch. I've been going over a lot of different solutions so things end up pretty messy. I have double checked everything and tried it all with and without password properly, same result – a.anev Jun 05 '22 at 17:04
  • 1
    Ok, that makes more sense - adding the password to the where clause is never going to match an existing row. `password_hash` doesn't return the same string every time you call it (for good reason). If you want to also check the password, you should be selecting all the columns you need (including the password) based on **only** the name, and then using `password_verify` in code. You still only need one query. See https://stackoverflow.com/questions/30279321/how-to-use-phps-password-hash-to-hash-and-verify-passwords – iainn Jun 05 '22 at 17:07
  • @iainn aah, interesting. I haven't touched php in a good few years and back when I was learning this stuff first this is how you did it with passwords. Encrypt it like in the register form and compare that. This makes sense. Before trying password_verify() I attempted to add a new user with an unencrypted password and query with an unencrypted password in the login screen and I'm getting "doesnt exist" on everything again – a.anev Jun 05 '22 at 17:44
  • @iainn update: I have attempted to use fetch() instead of fetchAll() which works only half the time. The older user names I have added up until now don't work but newly created ones do, very odd. This is without the exists(...) clause and I'm only querying for user names. – a.anev Jun 06 '22 at 13:18

0 Answers0