Предположим, что у нас на сайте есть система аутентификации пользователей. После регистрации мы просим пользователя пройти процедуру верификации email-а. Для создания подобных ссылок можем воспользоваться специальным параметром token. Пример подобной ссылки:
http://site.ua/activate?token=12dffd
Без базы данных тут нам не обойтись, поэтому давайте посмотрим на таблицу, с которой будем работать.
CREATE TABLE pending_users (
token CHAR(40) NOT NULL,
username VARCHAR(45) NOT NULL,
tstamp INTEGER UNSIGNED NOT NULL,
PRIMARY KEY(token)
);
В таблице будем хранить 3 поля: токен, имя пользователя и время. Для генерации токена мы воспользуемся функцией sha1(), которая выдаёт строку из 40 символов. Поле tstamp будет хранить время генерации токена для того, чтобы мы могли отследить ссылки с истёкшим сроком.
Существует множество способов генерации токена, однако в этом уроке мы воспользуемся функциями uniqid() и sh1(). Независимо от способа генерации токена, убедитесь что генерируемые значения будут разными и вероятность появления дубликатов минимальна.
$token = sha1(uniqid($username, true));
В качестве параметра функция uniqid() принимает строку, а на выходе даёт уникальный идентификатор, основанный на переданном аргументе и текущем времени. Также, в качестве второго аргумента, данная функция принимает булево значение, которое даст сигнал uniqid прибавить несколько дополнительных символов для увеличения вероятности уникальности значения. Функция sh1 принимает уникальный идентификатор и создаёт хэш.
После работы данных двух функций, у нас будет уникальный токен, который можем использовать для генерации url адресов. Теперь нам нужно занести его в базу:
Для того чтобы мы знали, какого пользователя следует активировать, в таблицу будем записывать и логин пользователя. В примере, более адаптированном для реального сайта, можете воспользоваться ID пользователя.
Теперь, когда у нас есть вся необходимая информация, можем создать временный url адрес:
Получившуюся ссылку можем отправить пользователю по email-у или каким-либо другим способом:
$message = <<<ENDMSG Thank you for signing up at our site. Please go to
$url to activate your account. ENDMSG;
mail($address, "Activate your account", $message);
Проверка
Теперь нам нужен скрипт, благодаря которому мы будем осуществлять проверку. Всё что нам нужно сделать, это сравнить токен из url адреса и токен из базы. Если такой имеется, и время его жизни не истекло, то всё ОК.
// получаем токен
if (isset($_GET["token"]) && preg_match('/^[0-9A-F]{40}$/i', $_GET["token"])) {
$token = $_GET["token"];
}
else {
throw new Exception("токен не валиден.");
}
// проверяем токен
$query = $db->prepare("SELECT username, tstamp FROM pending_users WHERE token = ?");
$query->execute(array($token));
$row = $query->fetch(PDO::FETCH_ASSOC);
$query->closeCursor();
if ($row) {
extract($row);
}
else {
throw new Exception("токен не валиден.");
}
// активируем пользовательский аккаунт
// ...
// удаляем токен из базы
$query = $db->prepare(
"DELETE FROM pending_users WHERE username = ? AND token = ? AND tstamp = ?",
);
$query->execute(
array(
$username,
$token,
$tstamp
)
);
Также нам нужно предусмотреть проверку токенов, время жизни которых истекло:
// 1 день в секундах = 60 секунд * 60 минут * 24 часа
$delta = 86400;
// проверка
if ($_SERVER["REQUEST_TIME"] - $tstamp > $delta) {
throw new Exception("время жизни токена истекло.");
}
// активируем пользовательский аккаунт
// ...
Таким образом, у нас будут осуществляться две проверки: одна на валидность токена, другая на время его существования.