Восстановление пароля.

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Аватара пользователя
mum
Сообщения: 123
Зарегистрирован: 2011.12.15, 19:45
Контактная информация:

Восстановление пароля.

Сообщение mum »

Продолжаю изучение yii =)

Написал регистрацию, где ввод только емайла и логина, пароль генерируется автоматом и высылается на эмайл.
Соль хранится у в таблице, для каждого пользователя индивидуальная)

Сейчас написал восстановление пароля, где высылается ссылка с id и md5(соль)
Ссылки на эмайл приходят такие site.ru/restore/id/md5(salt)

Сам Экшен восстановления:

Код: Выделить всё

public function actionRestore_password()
    {
        $model = new User('restore_password');
        if(!empty($_GET['id']) && !empty($_GET['restore']))
        {
            $user = User::model()->findByAttributes(array('id'=>$_GET['id']));
            if($user != null && md5($user['salt']) == $_GET['restore']){
                $randomPass = User::model()->randomPass();
                $model = User::model()->findByPk($user['id']);
                $model->password = User::model()->hashPassword($randomPass, $user['salt']);
                
                if($model->save(false)){
                    $message = new YiiMailMessage;
                    $message->view = 'change_password';
                    $message->setBody(array('login'=> $user['login'], 'password'=>$randomPass, 'host'=>Yii::app()->params['host'], 'host_name'=>Yii::app()->params['host_name']), 'text/html');
                    $message->addTo($user->email);
                    $message->setSubject(Yii::app()->params['email_restore_password_subject']);
                    $message->from = Yii::app()->params['email_no-reply'];
                    Yii::app()->mail->send($message);
                
                    Yii::app()->user->setFlash('success', '<strong>Success!</strong> Your password has been successfully changed and sent to you by e-mail.');
                    Yii::app()->user->setState('login', $user['login']);
                    $this->redirect(array('user/login'));
                }
            }
        }
        if(!empty($_POST['User'])){
            $model->attributes = $_POST['User'];
            $user = User::model()->findByAttributes(array('email'=>$model->email));
            if($model->validate()){
                if($user == null){
                    Yii::app()->user->setFlash('error', '<strong>Error!</strong> No such user exists.');
                }
                else{
                    $message = new YiiMailMessage;
                    $message->view = 'restore_password';
                    $message->setBody(array('login'=> $user['login'], 'id'=>$user['id'], 'link'=>md5($user['salt']), 'host'=>Yii::app()->params['host'], 'host_name'=>Yii::app()->params['host_name']), 'text/html');
                    $message->addTo($model->email);
                    $message->setSubject(Yii::app()->params['email_restore_password_subject']);
                    $message->from = Yii::app()->params['email_no-reply'];
                    Yii::app()->mail->send($message);
                    
                    Yii::app()->user->setFlash('success', '<strong>Success!</strong> Recovery information sent to you by e-mail.');
                }
            }
        }
        $this->render('restore_password', array(
                      'model' => $model,
        ));
    }
 
Вопрос такой, нечего страшного что я выдаю соль в шифровании? для восстановления.
и как лучше получать гет, просто $_GET или Yii:app()->getRequest()->getQuery();

PS просто учусь и хочу сделать все по уму.
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: Восстановление пароля.

Сообщение lancecoder »

где высылается ссылка с id и md5(соль)
вы серьезно???
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: Восстановление пароля.

Сообщение lancecoder »

мм дочтав пост посоветую ид ваще не показывать и прост о соли мало, ей вообщ лучшше не оперировать это "серверная часть"
Аватара пользователя
mum
Сообщения: 123
Зарегистрирован: 2011.12.15, 19:45
Контактная информация:

Re: Восстановление пароля.

Сообщение mum »

lancecoder привет)
Мне сказали что для восстановления проще использовать мыло в md5, и все, то есть этим можно обойтись, а как тогда искать?) или проще использовать встроенное yii шифрование Yii::app()->securityManager->encrypt($value)?
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: Восстановление пароля.

Сообщение lancecoder »

логин мд5 тоже по левому, случайное число\строка надо в хеше (в любом в принципе)
Аватара пользователя
mum
Сообщения: 123
Зарегистрирован: 2011.12.15, 19:45
Контактная информация:

Re: Восстановление пароля.

Сообщение mum »

ясно, проблематично) я хотел без доп. строк, в таблице юзера придется создать.
Аватара пользователя
vova07
Сообщения: 1004
Зарегистрирован: 2012.11.29, 14:52
Откуда: Chisinau, Moldova

Re: Восстановление пароля.

Сообщение vova07 »

Если у вас есть поле last_update, то можно использовать ее.
А поиск все таки делать лучше по Логину, ну и проверять уже значение поля "последнее обновление"
Аватара пользователя
mum
Сообщения: 123
Зарегистрирован: 2011.12.15, 19:45
Контактная информация:

Re: Восстановление пароля.

Сообщение mum »

last_update есть, только я не пойму как) его кодировать и отправлять?
Аватара пользователя
vova07
Сообщения: 1004
Зарегистрирован: 2012.11.29, 14:52
Откуда: Chisinau, Moldova

Re: Восстановление пароля.

Сообщение vova07 »

В общем для безопасной смены пароля лучше делать так :
При отправки формы восстановления, вы меняете пароль в базе по указанному имейлу, или логину, (естественно он в базе уже закодированный по вашему хешу), в это же время вы обновляете "last_update". Функционально смена пароля на этом закончилась, теперь отправляете ссылку и пароль юзеру. Можно так : пароль он у вас там наверное рандомно генерится, и его отправляете как он есть, ну и еще что вы хотите отправить, а ссылку формируете примерно так : site.ru/restore/login/md5(last_update) .... при заходе на эту ссылку вы проверяете если значение $_GET['last_update'] совпадает с md5(last_update) у пользователя с указанным логином.
Все готово! Суть в том что хеш для отправки можно использовать вообще другой, отличающийся от того что кодирует пароль.
Надеюсь суть поняли.
Аватара пользователя
mum
Сообщения: 123
Зарегистрирован: 2011.12.15, 19:45
Контактная информация:

Re: Восстановление пароля.

Сообщение mum »

Понял, спасибо)
vtec
Сообщения: 49
Зарегистрирован: 2010.11.16, 10:28

Re: Восстановление пароля.

Сообщение vtec »

vova07 писал(а):В общем для безопасной смены пароля лучше делать так :
При отправки формы восстановления, вы меняете пароль в базе по указанному имейлу, или логину, (естественно он в базе уже закодированный по вашему хешу), в это же время вы обновляете "last_update". Функционально смена пароля на этом закончилась, теперь отправляете ссылку и пароль юзеру. Можно так : пароль он у вас там наверное рандомно генерится, и его отправляете как он есть, ну и еще что вы хотите отправить, а ссылку формируете примерно так : site.ru/restore/login/md5(last_update) .... при заходе на эту ссылку вы проверяете если значение $_GET['last_update'] совпадает с md5(last_update) у пользователя с указанным логином.
Все готово! Суть в том что хеш для отправки можно использовать вообще другой, отличающийся от того что кодирует пароль.
Надеюсь суть поняли.
Я как понимаю при отправке формы восстановления менять пароль в базе неверно.
Вернее будет так: заполняется форма, если все условия выполняются то отправляется хэш на email (лучше все таки его сохранить) и только если пользователь переходит по ссылке из письма, то тогда меняем пароль. А то может получится так: зная email пользователей я могу на восстанавливать и по сбрасывать пароли тем кто даже в этом не нуждается!

Если не так, то расскажите как у вас?

Еще скажите если есть одно поле для восстановления пароля и в него я могу ввести логин или пароль для восстановления, то какая проверка в reles должна быть?
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: Восстановление пароля.

Сообщение lancecoder »

сори, но бред конечно, это че я могу всем пароли попоменять?
восстановить пароль - Вася
восстановить пароль - Петя
Петя и Вася удивятся при заходе на сайте :)

я реализовывал через доп таблицу tasks
и у пользователя есть поле статус (Registered, Task) примерно так, в таск заносятся все задачи пользователя которые требует сайт - активация, восстановления пароля, смена мыла и т.д.
т.е. если я нажал восстановить пароль, то в таск я вношу строку
user_id, type, hash
если ктото сбросил пароль, а юзер залогонился под своим старым, тогда удаляется задача и юзер снова активен, иначе ждет хеша подтверждающего действие
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: Восстановление пароля.

Сообщение lancecoder »

упс, не увидел про "понаменять пароли" в речах предыдущего оратора
Аватара пользователя
vova07
Сообщения: 1004
Зарегистрирован: 2012.11.29, 14:52
Откуда: Chisinau, Moldova

Re: Восстановление пароля.

Сообщение vova07 »

Как я помню, то что я писал было как вариант решения конкретной поставленной задачи, несмотря на то что сам такого не делаю.
Я обычно при восстановлении пароля деактивирую пользователя, таким образом на электронный адрес пользователя что в БД отправляется новый рандом код ... с его помощью можно снова активировать учётную запись, и сразу же поменять забытый пароль.
Да чтоб полностью было понятно ... восстановление идёт по e-mail-у который нигде на сайте никогда не выводится, таким образом знает его только владелец аккаунта.
vtec
Сообщения: 49
Зарегистрирован: 2010.11.16, 10:28

Re: Восстановление пароля.

Сообщение vtec »

Скажите, а как быть с:
если есть одно поле для восстановления пароля и в него я могу ввести логин или пароль для восстановления, то какая проверка в reles должна быть?
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: Восстановление пароля.

Сообщение rak »

vtec писал(а): если есть одно поле для восстановления пароля и в него я могу ввести логин или пароль
:shock:
имелось ввиду логин или емейл?
vtec
Сообщения: 49
Зарегистрирован: 2010.11.16, 10:28

Re: Восстановление пароля.

Сообщение vtec »

Упс :), да имелось ввиду логин или email.
vtec
Сообщения: 49
Зарегистрирован: 2010.11.16, 10:28

Re: Восстановление пароля.

Сообщение vtec »

up
если есть одно поле для восстановления пароля и в него я могу ввести логин или email для восстановления, то какая проверка в reles должна быть?
safe пойдет?
Bloom
Сообщения: 313
Зарегистрирован: 2013.02.25, 12:57

Re: Восстановление пароля.

Сообщение Bloom »

Мое решение:
В базе у каждого пользователя есть поле activation, куда записывается сложный хэш или строка случаных символов. Она используется для активации аккаунта.
Во время активации код изменяется так-же на рандомное значение, чтобы пользователь не мог пройти активацию несколько раз.

Теперь решение задачи:
Пользователь решил восстановить пароль (получить новый). У нас есть его e-mail. Мы отправляем на почту ссылку вида site.ru/newpass/activKey
где activeKey - тот самый ключ из поля activation.
После перехода по ссылке ему выдаем окошко для ввода нового пароля (если конечно совпало значение ключа). Либо показываем ему новый пароль, или отправляем новый пароль на почту или еще как-нибудь.. но только после того, как ключик совпал.
Что мы имеем в конце? Кто угодно, сколько угодно раз может пытаться восстанавливать пароли пользователей - они не поменяются до тех пор, пока реальный пользователь не зайдет на почту и не перейдет по ссылке.
Аватара пользователя
mum
Сообщения: 123
Зарегистрирован: 2011.12.15, 19:45
Контактная информация:

Re: Восстановление пароля.

Сообщение mum »

Решил проблему давно, но отпишусь.
Я не вижу смысла при отправки запроса на восстановления пароля, сразу высылать пароль. Так как тролей в интернете как слон насрал.
Ну и не факт что новичек не решится проверить почту, что у него восстановление пароля и не сможет зайти на Ваш ресурс.
Решил проблему таким образом.
На сайте ведется запись последнего входа пользователей таблице users строка last_update и строка recovery
В строку recovery при регистрации заносим случайный код можно даже генерировать.
При каждом входе на сайт last_update меняется добавить функцию можно в компонент WebUser

Код: Выделить всё

function afterLogin() {
//обновление
} 
При запросе на восстановление высылаем ссылку site.ru/recovery/md5(last_update.recovery)
При переходе по ссылке высылать новый пароль или форму на восстановление ну и сгенерирывать новый новый случайный код recovery.
Можно было проще сделать просто last_update формата NOW(); или просто хороший хеш для recovery =)
Плюсы что если даже юзер отправил запрос на восстановление и вспомнил пароль, он сможет зайти без лишних проблем, ну и тролям немного руки вывернуть)
Сильно не ругать, это всего лишь моя идея.
Ответить