Меняем механизм восстановления пароля

+12
1.78K
Все мы знаем, что изменения пароля, при восстановлении происходит сразу, не спрашивая подтверждения пользователя, попробуем изменить это.

Если было, сильно не пинать, делал для себя, решил поделиться.

Открываем файл components/registration/frontend.php

Ищем условие if ($do==’passremind’){

меняем его содержимое на
  1. if ($do=='passremind'){
  2.  
  3. $inPage->setTitle($_LANG['REMINDER_PASS']);
  4. $inPage->addPathway($_LANG['REMINDER_PASS'], $_SERVER['REQUEST_URI']);
  5.  
  6. echo '<div class="con_heading">'.$_LANG['REMINDER_PASS'].'</div>';
  7.  
  8. if (!isset($_POST['goremind'])){
  9. //PRINT QUERY FORM
  10. echo '<form name="prform" action="" method="POST">';
  11. echo '<table style="background-color:#EBEBEB" cellspacing="0" cellpadding="9"><tr>';
  12. echo '<td>'.$_LANG['WRITE_REGISTRATION_EMAIL'].': </td>';
  13. echo '<td><input name="email" type="text" size="25" /></td>';
  14. echo '<td><input name="goremind" type="submit" value="'.$_LANG['SEND'].'"/></td>';
  15. echo '</tr></table>';
  16. echo '</form>';
  17. } else {
  18. //SEND NEW PASSWORD TO EMAIL
  19. $email = $_POST['email'];
  20.  
  21. if (!preg_match('/^([a-z0-9\._-]+)@([a-z0-9\._-]+)\.([a-z]{2,4})$/i', $email)){
  22. echo '<p style="color:red">'.$_LANG['ERR_EMAIL'].'</p>';
  23. } else {
  24.  
  25. $sql = "SELECT * FROM cms_users WHERE email = '$email' LIMIT 1";
  26. $result = $inDB->query($sql) ;
  27.  
  28. if ($inDB->num_rows($result)>0){
  29. $usr = $inDB->fetch_assoc($result);
  30.  
  31. //Если запрашивается повторно, то старую запись с кодом подтверждения удаляем
  32. $sql = "DELETE FROM cms_users_activatepass WHERE user_id = '".$usr['id']."' ";
  33. $result = $inDB->query($sql);
  34.  
  35. $code = substr(md5(microtime()) . md5(rand(0, 9999)), 0, 32);
  36. $codelink = 'http://'.$_SERVER['HTTP_HOST'].'/activatepass/'.$code;
  37. $newpassword = substr(md5(microtime()) . md5(rand(0, 9999)), 0, 8);
  38.  
  39. $sql = "INSERT INTO cms_users_activatepass (pubdate, user_id, code, pass)
  40. VALUES ('".time()."', '".$usr['id']."', '".$code."', '".md5($newpassword)."')";
  41. $inDB->query($sql) or die($_LANG['ERR_SEND_ACTIVATION_MAIL']);
  42.  
  43. $mail_message = $_LANG['HELLO'].', ' . $usr['nickname'] . '!'. "\n\n";
  44. $mail_message .= $_LANG['REMINDER_TEXT'].' "'.$inConf->sitename.'".' . "\n\n";
  45. $mail_message .= $_LANG['OUR_PASS_IS_MD5'] . "\n";
  46. $mail_message .= $_LANG['OUR_PASS_IS_MD5_TEXT'] . "\n\n";
  47. $mail_message .= $_LANG['REMINDER_TEXT_1'] . "\n\n" .$codelink. "\n\n";
  48. $mail_message .= $_LANG['REMINDER_TEXT_2'] . "\n\n";
  49. $mail_message .= '########## '.$_LANG['YOUR_LOGIN'].': ' .$usr['login']. "\n\n";
  50. $mail_message .= '########## '.$_LANG['YOUR_NEW_PASS'].': ' .$newpassword . "\n\n";
  51. $mail_message .= $_LANG['YOU_CAN_CHANGE_PASS']."\n";
  52. $mail_message .= $_LANG['IN_CONFIG_PROFILE'].': '. cmsUser::getProfileURL($usr['login']) . "\n\n";
  53. $mail_message .= $_LANG['SIGNATURE'].', '. $inConf->sitename . ' ('.HOST.').' . "\n";
  54. $mail_message .= date('d-m-Y (H:i)');
  55.  
  56. $inCore->mailText($email, $inConf->sitename.' - '.$_LANG['REMINDER_PASS'], $mail_message);
  57. echo '<p>'.$_LANG['NEW_PAS_SENDED'].'</p>';
  58.  
  59. } else {
  60. echo '<p style="color:red">'.$_LANG['ADRESS'].' "'.$email.'" '.$_LANG['NOT_IN_OUR_BASE'].'</p>';
  61. }
  62.  
  63. }
  64. }
  65.  
  66. }
Добавим новое условие проверки при активации нового пароля

  1.  
  2. if ($do=='activatepass'){
  3.  
  4. //Удаляем "просроченные" записи
  5. $sql = "DELETE FROM cms_users_activatepass WHERE pubdate < '".(time()-(60*60*24))."' ";
  6. $inDB->query($sql);
  7.  
  8. $code = $inCore->request('code', 'str', '');
  9.  
  10. if (!$code) { $inCore->redirect('/'); exit; }
  11.  
  12. $sql = "SELECT * FROM cms_users_activatepass WHERE code = '".$code."' ";
  13. $result = $inDB->query($sql);
  14.  
  15. if($inDB->num_rows($result)==1) {
  16. $row = $inDB->fetch_assoc($result);
  17.  
  18. $sql = "UPDATE cms_users SET password = '".$row['pass']."' WHERE id = '".$row['user_id']."' ";
  19. $inDB->query($sql) or die($_LANG['ERR_ACTIVATION']);
  20.  
  21. $sql = "DELETE FROM cms_users_activatepass WHERE code = '$code'";
  22. $inDB->query($sql) or die($_LANG['ERR_ACTIVATION']);
  23.  
  24. echo '<p>'.$_LANG['NEW_PAS_SUBMITED'].'</p>';
  25.  
  26. } else {
  27. echo '<p style="color:red">'.$_LANG['CODE_NOT_FOUND'].'</p>';
  28. }
  29.  
  30. }
  31.  
Добавим новые языковые переменные в ланг файл languages/ru/components/registration.php

  1.  
  2. $_LANG['REMINDER_TEXT_1'] ='Для смены пароля перейдите по ссылке';
  3. $_LANG['REMINDER_TEXT_2'] ='Если Вы не запрашивали смену пароля, просто проигнорируйте данное письмо.';
  4. $_LANG['NEW_PAS_SUBMITED'] ='Ваш пароль успешно изменен.';
  5. $_LANG['CODE_NOT_FOUND'] ='Извините, код активации не найден.';
  6.  
Изменим там же одну строку
с
  1. $_LANG['NEW_PAS_SENDED'] ='Новый пароль был выслан на указанный e-mail.';
  2.  
на
  1. $_LANG['NEW_PAS_SENDED'] ='Инструкция по активации нового пароля была выслана на указанный e-mail.';
  2.  
Далее для создаем в корне файл custom_rewrite.php (если его еще не было, если уже есть то просто добавим строки)
с содержимым
  1.  
  2. <?php
  3.  
  4. function custom_rewrite_rules(){
  5.  
  6.  
  7. $rules[] = array(
  8. 'source' => '/^activatepass\/(.+)$/i',
  9. 'target' => 'registration/activatepass/{1}',
  10. 'action' => 'rewrite'
  11. );
  12.  
  13. return $rules;
  14.  
  15. }
  16.  
  17. ?>
  18.  
Также добавим новое правило для ЧПУ в components/registration/router.php
  1.  
  2. $routes[] = array(
  3. '_uri' => '/^registration\/activatepass\/(.+)$/i',
  4. 'do' => 'activatepass',
  5. 1 => 'code'
  6. );
  7.  
Добавим новую таблицу в базу данных, в которой будут храниться хэш нового пароля и код его активации

  1.  
  2. CREATE TABLE `cms_users_activatepass` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `pubdate` int(11) NOT NULL,
  5. `user_id` int(11) NOT NULL,
  6. `code` varchar(50) NOT NULL,
  7. `pass` varchar(50) NOT NULL,
  8. PRIMARY KEY (`id`)
  9. ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
  10.  
Все, теперь при запросе нового пароля, пользователю будет отправляться email с сылкой подтверждения для
применения пароля, если пользователь не изменит его в течении суток, то придется процедуру повторить заново.

Архив с уже измененными файлами здесь
+11
Hmelex Hmelex 14 лет назад #
Может Администраторы посмотрят и выскажет свой мнение по этому поводу...(для внесения в новый релиз) zst
+3
mihalich mihalich 14 лет назад #
Согласен весч нужная, а то заведётся на сайте троль какой нибудь(знающий почту человека) и будет кому нибудь пароли восстанавливать.
+2
mihalich mihalich 14 лет назад #
Судя по нашим плюсам с нами согласны на данный момент ещё 10 человек! smile
+7
14 лет назад #
Схема восстановления должна быть другая, без всяких временных таблиц и автогенерации бестолкового пароля, который он опять забудет ))
1. Человек забыл пароль, вводит email в форме восстановления
2. Приходит письмо с текстом, "Вы запросили новый пароль, перейдите по ссылке", которая ведёт на форму, в которой он САМ вводит новый пароль. Ссылка должна быть специально сформирована, например site.ru/login/?auth=asdf564ewrsdf546asdf, по которой он сможет автоматически авторизоваться, т.е. содержать некий секретный ключ, например это может быть md5 на user_id + user_email + user_password, это гарантирует нам что ключ будет разный при смене пароля, и злоумышленнику будет практически невозможно её сформировать
3. И в почту никакие пароли не приходят, т.е. его будет знать только один юзер.
4. Профит!
0
Atheist Atheist 14 лет назад #
А разве долго после первого захода сменить пароль на более удобный, или он его тоже забудет. laugh
0
ГеймОверСистемХалтед ГеймОверСистемХалтед 14 лет назад #
Долго, просто забудут и все. ))
0
Atheist Atheist 14 лет назад #
Так они если и сами введут, то тут же забудут hoho
0
Atheist Atheist 14 лет назад #
2bibendi так написал бы и предложил всем, а писать посты мы все умеем
+3
Fuze Fuze 14 лет назад #
Понимаю твое возмущение, но bibendi дело говорит. Такие слова надо воспринимать как адекватную критику. Лучше было бы если написали в каментах типа "ацтой, полная фигня"?

Если действительно попробовать переделать так, как bibendi предложил?
0
Atheist Atheist 14 лет назад #
Извиняюсь, погорячился, переделать можно, но считаю, что без временной таблицы все равно не обойтись, в ней нужно хотя бы хранить информацию, о том что именно этот юзер запросил смену пароля, чтобы не проверять всех подряд. Время будет, посмотрю что можно сделать. smile
+1
14 лет назад #
Я в проекте instantcms с самого его основания всего лишь как консультант и модератор. На большее (писать код) времени абсолютно нет, да и PHP в последнее время не очень люблю, уж извиняйте smile
0
Otus7 Otus7 14 лет назад #
Если PHP не любишь, то что любишь? )
0
14 лет назад #
Ну последние 5 месяцев пишу только на фреймворке Ruby on Rails.
Руби - это просто сказочный язык joke
0
mihalich mihalich 14 лет назад #
Дело говорит и создатель блога и товарищ bibendi, в любом случае это должно присутствовать. Так как сейчас, зная почту человека, извиняюсь за выражение можно так ему поднасрать.А если написать скрипт по восстановлению пароля....
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.