Предположим, что у нас на сайте есть система аутентификации пользователей. После регистрации мы просим пользователя пройти процедуру верификации 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 адресов. Теперь нам нужно занести его в базу:

$query = $db->prepare(
"INSERT INTO pending_users (username, token, tstamp) VALUES (?, ?, ?)"
);
$query->execute(
array(
$username,
$token,
$_SERVER["REQUEST_TIME"]
)
);

Для того чтобы мы знали, какого пользователя следует активировать, в таблицу будем записывать и логин пользователя. В примере, более адаптированном для реального сайта, можете воспользоваться ID пользователя.

Теперь, когда у нас есть вся необходимая информация, можем создать временный url адрес:

$url = "http://site.ru/activate.php?token=$token";

Получившуюся ссылку можем отправить пользователю по 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("время жизни токена истекло.");
}
// активируем пользовательский аккаунт
// ...

Таким образом, у нас будут осуществляться две проверки: одна на валидность токена, другая на время его существования.
1 2 0
Без комментариев...