Я надеюсь, что существует стандартный сценарий class / php, который мы можем использовать для функции «забытый пароль». Кажется, он есть почти на каждом веб-сайте, и я бы хотел сократить время его разработки.
Похоже, что общий подход:
Я не хочу делать это с нуля, надеюсь, что кто-то, продумавший какие-либо нюансы, может указать мне на уже существующий код. Казалось бы, это довольно стандартизировано.
Все: получил несколько ответов, но я надеюсь, что, возможно, кто-то сможет порекомендовать довольно стандартный класс или CMS, которые соответствуют общепринятым правилам безопасности.
ребята, извините за мой первый комментарий
Спасибо, что встал перед человеком, Джоэл!
Вы должны повторно использовать существующую структуру аутентификации, когда это возможно, потому что на самом деле это сложно. Например, взгляните на github.com/delight-im/PHP-Auth, который не зависит от платформы и базы данных.






Вы можете украсть его из самых разных фреймворков / CMS. Drupal, Kohana и т. д.
Я использую qcodo, который, похоже, не имеет встроенного ... что мне показалось странным ....
Для сброса пароля использую собственные скрипты.
Я создаю таблицу для хранения user_id, случайного ключа и времени, когда сброс пароля инициировал:
// query is my own SQLite3 wrapper function which ensures I have a valid database connection then executes the SQL.
// I would imagine small changes will be needed to the SQL for MY SQL.
query("create table reset_password (user_id integer not null default 0, key text not null default '', time integer not null default 0)");
query("create unique index reset_password_user_id on reset_password (user_id)");
query("create index reset_password_key on reset_password (key)");
Затем, когда необходимо сбросить пароль, вызывается следующий код:
// $user_id must be an integer that matches a valid user's ID.
function reset_password($user_id) {
query("delete from reset_password where user_id = $user_id");
$key = substr(base64_encode(crypt('', '')), 0, 32);
query("insert into reset_password values ($user_id, '$key', " . time() . ")");
// fetch is my own wrapper function to fetch a row from the query.
$f = fetch(query("select username from users where id = $user_id"));
// smtp is my own function, you will probably want to use the php mail function.
smtp(
"[email protected]", // sender
$f['username'], // recepient
"From: The example.com Web Site <[email protected]>\r\n" . // email headers
"To: {$f['username']} <{$f['username']}>\r\n" . // actual email address <put a nice friendly name in here if you have the the information>
'Subject: Reset Password' . "\r\n" .
"\r\n" .
"Hello\r\n" . // email body
"\r\n" .
"A request has been made to reset your example.com web site password.\r\n" .
"\r\n" .
"To complete the request, click on the following link within 48 hours of the transmision of this email and follow the on screen instructions.\r\n" .
"\r\n" .
/// URL is defined as the root of the URL used in the email, in this example it would be "http://example.com/"
URL . "index.php?page=reset-password&user_id = " . urlencode($user_id) . "&key = " . urlencode($key) . "\r\n" .
"\r\n" .
"Kind regards,\r\n" .
"\r\n" .
"The example.com Web Site"
);
}
При щелчке по ссылке в электронном письме отображается страница, содержащая следующее:
// form, input_hidden, table, tr, td, label, input_password and input_submit are my own wrappers which return the appropriate HTML with escaped values where required.
echo
form('reset-password/ok',
input_hidden('user_id', $_GET['user_id']) .
input_hidden('key', $_GET['key']) .
table(
tr(
td(label('New Password')) .
td(input_password('new_password', ''))
) .
tr(
td(label('Confirm Password')) .
td(input_password('confirm_password', ''))
)
) .
input_submit('ok', 'OK')
);
При отправке вышеуказанной формы выполняется следующее:
// The reset_password_message function displays the message to the user.
if (!isset($_POST['user_id'])) {
reset_password_message('You must enter a user ID. Please try again.');
} else if (!isset($_POST['key'])) {
reset_password_message('You must enter a key. Please try again.');
} else if (!isset($_POST['new_password']) || !$_POST['new_password']) {
reset_password_message('You must enter a new password. Please try again');
} else if (!isset($_POST['confirm_password']) || $_POST['new_password'] != $_POST['confirm_password']) {
reset_password_message('The new password and the confirmation do not match. Please try again.');
} else if (!$f = fetch(query("select time from reset_password where user_id = " . (integer)$_POST['user_id'] . " and key = '" . escape($_POST['key']) . "'"))) {
reset_password_message('The user ID and key pair are invalid. Please try again.');
} else if ($f['time'] < time() - 60 * 60 * 24 * 2) { // 60 seconds * 60 minutes * 24 hours * 2 days (48 hours as explained in the email sent to the user above).
reset_password_message('The user ID and key pair have expired. Please try again.');
} else {
query("update users set password = '" . crypt($_POST['new_password']) . "' where id = " . (integer)$_POST['user_id']);
reset_password_message('Your password has been reset. Please login.');
}
Вы можете использовать этот код вместо «собственного», но вам нужно будет внести несколько изменений или добавить несколько функций, чтобы завершить его.
Привет, Стейси Ричардс, я следую твоему методу. Скажите, как мне обрабатывать несколько имен пользователей, используя один и тот же адрес электронной почты? Я считаю, что мне нужно сгенерировать уникальный «случайный ключ» для каждого «имени пользователя», а затем доставить письма ... Спасибо
Нет, это хорошо. Это именно то, что нужно для SO. Аутентификация сложна, и в ней легко ошибиться тонкими способами, которые не обнаруживаются до тех пор, пока после ваш сайт не был взломан. В этом случае проверка стандартного сценария, о котором он может не знать, является частью работы.