Now, there might also be a problem in the password field definition in the table spec: password varchar(20) NOT NULL
. As far as I remember the good old MD5 produces a hash of lenght that fits into CHAR(32). So password hashes stored in the users table could be truncated due to too small filed size and therefore can not match even if the user entered correct password.
However, more important fact here is that MD5 has been unfit for password hashing for years. It is completely unsecure and do not use it in any production site. There is much more suitable function password_hash
(https://www.php.net/manual/en/function.password-hash.php) built into PHP. If you use it you must also make you password field bigger, maybe 255 characters to be ready for future.