Из всего изложенного выше - наиболее оптимальным вариантом вижу хранение в сессии сериализованного(
json_encode,
serialize) массива из ID(или логина, при условии его уникальности) юзера и хеша пароля. При смене пароля - все старые сессии отпадают.
Категорически
не рекомендую и использовать проверки по IP и User Agent.
При проверке по IP - отпадают пользователи на динамических IP(это те же мобильные операторы).
При проверке User Agent - сессия будет слетать при каждом обновлении браузера(т.к. User Agent в этом случае тоже меняется). А все современные браузеры обновляются очень часто и в автоматическом режиме.
Еще как вариант(более параноидальный) - можно генерировать рандомный хеш sha256(или sha1, md5, без разницы), заносить этот хеш в бд рядом с ID юзера. Затем записывать пользователю две куки - с id и с этим хешем. При посещении проверять эти два параметра.