Вот пара занимательных статей на эту тему:
blgo.ru/blog/2014/07/18/regform
blgo.ru/blog/2014/07/24/regform-112
А вообще, алгоритм примерно такой:
Врубаем https, при регистрации хэшируем пароль с солью и статичиским ключиком. Примерно так:
$staticKey = "Your static key";
$salt = %random string with diggits%;
$password = sha1($_POST['password'] . $staticKey . $salt);
// save to db $salt and $password
Для авторизации проверяем соответствие пароля:
$staticKey = "Your static key";
$salt = %salt from db%;
$password = sha1($_POST['password'] . $staticKey . $salt);
return $password == $dbPassword; // Авторизация удалась
Теперь можем создать сессию и записать в нее данные для авторизации. Если исользуем свой механизм сессий, то тут можно предусмотреть несколько вариантов для защиты:
1. Повторный ввод пароля, если пользователь зашел из необычного места (определяем по ip/геолокации, например). Сегодня он в России, завтра он в Австралии, стоит проверить пароль еще раз. Проверку не проходит, скидываем сессию.
2. Сессия была в одном браузере, затем, та же сессия, в другом. Странное поведение, просим ввести пасс.
3. Можем раз в пол часа обновлять идентификатор сессии в куках у юзера.
4. etc.