Минимум, который должен быть всегда
Пароль хэшируется Argon2id или bcrypt и никогда не попадает в журнал. После успешного входа идентификатор сессии меняется. Cookie получает HttpOnly, Secure и подходящий SameSite.
Ошибки входа формулируются одинаково: не сообщайте, существует ли почта. Добавьте ограничение частоты по IP и учётной записи, но не превращайте его в вечную блокировку.
Для административных прав включите второй фактор и журнал важных действий. Это небольшой набор мер, который закрывает большинство бытовых атак.