В чем ошибка моего кода?
Самое время познакомиться с темной стороной программирования. 
Начинающие вайтишники искренне думают, что программист - это типа такой художник. Берет мольберт, поллитру, кисти и начинает ВАЯТЬ. Потом отходит на шаг, любуется делом рук своих, и снова. Ваять. А потом сразу заказчику, за большие деньги. 

Так вот,  в реальности это всё не так.
Большую часть времени программист не пишет код.
А пытается разобраться, почему он не работает. 

Так что мы будем сейчас учиться это делать. 
Тем более, что это в принципе несложно. 
Главное не думать, что чем-то поможет сидеть и тупить в свой кодик. И приглашать других людей потупить в него тоже бессмысленно. Потому что причина может быть совсем не в нем. но даже если проблема и в коде, то искать её всё равно надо по-другому. 
В код не надо тупить. Его надо ЗАПУСКАТЬ.
И выводить промежуточные результаты. Проверять его работу. 
Заранее выяснить, какие должны быть значения у переменных, и проверять их на каждом этапе.
Где не совпадут - там и проблема. 
В идеале IDE сама покажет содержание всех переменных при трассировке, но если пишешь код в блокнотике, то даже тупо писать var_dump($bar1,$var2,$var3...); и смотреть что там лежит.
Условия проверять еще проще, тупо echo 'зашли в условие if (!empty($user))';
И если лежит не то, или эхо не выводится - вот тогда уже смотреть в код и думать, почему так получилось.

В частности, при авторизации надо проверить две вещи:
1. Находится ли юзер по логину
2. если находится, то проверить корректность хэша. Для этого при регистрации надо вывести полученный через password_hash пароль и записать на бумажке
потом запросить сохраненный из БД и сравнить

Кроме того
Разумеется, отладка невозможна без сообщений об ошибках. 
В половине случаев РНР человеческим голосом сообщает в чем проблема. 
Поэтому всегда, в любом окружении должно стоять error_reporting(E_ALL);
плюс на домашнем компике полезно прописать ini_set('display_errors', 1); чтобы сразу видеть ошибки на экране. 
На боевом сервере разумеется поставить 0 вместо 1, и добавить  ini_set('log_errors', 1);

У меня только один вопрос.
Какой смысл вообще делать парольную защиту, если любой придурок сможет спокойно авторизоваться через SQL инъекцию?
Если не делаешь через подстановочные знаки вопроса, то используй тогда функцию mysqli::real_escape_string, а то реально и инъекция будет, и любой специальный символ всё сломает и так далее.