Быстрый лёгкий надёжный форумный движок
Вы не вошли.
Страницы 1
Тема закрыта
Ниже приводится пример универсальной интеграции форума с любым движком, в основе которой лежат простые http-запросы к скриптам. Скрипты, в свою очередь, регистрируют пользователей и логинят их.
Данный подход используется на http://pupser.ru (сам сайт сделан на Ruby On Rails).
Для интеграции нам требуются три скрипта:
[li]скрипт регистрации, принимает в качестве параметров логин пользователя, пароль, email и ip[/li][li]скрипт входа на форум, принимает в качестве параметров логин и пароль[/li][li]скрипт смены пароля, принимает в качестве параметров логин и новый пароль[/li]
Благодаря этим скриптам мы сможем синхронизировать пользователей сайта (движка) и пользователей форума, и обеспечивать единообразный вход на сайт и на форум (через сайт).
Чтобы данный подход был безопасным (только движок мог работать с пользователями форума), можно использовать либо защиту по ip (например, ip движка - 192.168.1.10, запросы к скриптам с других ip-адресов будут игнорироваться), либо защиту с магическим ключом (одним из параметров запроса передаётся магический ключ, он сверяется либо с хэш-функцией от других параметров запроса и заранее заданного слова, либо с содержимым базы).
Рассмотрим защиту с помощью базы данных: движок сайта генерирует магический ключ, записывает его в базу, и выполняет запрос скрипта форума. Скрипт форума, в свою очередь, получив магический ключ, ищет этот ключ в базе, и проверяет время создания ключа (скажем, ключ должен быть создан не позднее минуты назад). Соответственно, некая третья сторона (злоумышленник), не имея доступа к базе, не сможет выполнять запросы к скриптам форума для регистрации юзеров, смены паролей, и прочее.
Непосредственно примеры php-скриптов (исходим из того, что их надо поместить в подкаталог interface каталога форума):
Скрипт регистрации:
/forum/interface/register.php?username=...&password=...&magick_key=...&email=...&ip=...
[mono]
<?php
// request should contain
// magick_key
// username
// password
// email
// ip
require_once('mkeys.inc.php');
if (!checkMagickKey($_REQUEST['username'], $_REQUEST['magick_key']))
{
echo "ERROR: invalid magick key";
exit();
}
define('PUN_ROOT', '../');
require_once PUN_ROOT.'config.php';
require_once PUN_ROOT.'include/dblayer/common_db.php';
require_once PUN_ROOT.'include/functions.php';
// registration
$edit = array(
'pass' => $_REQUEST['password'],
'name' => $_REQUEST['username'],
'mail' => $_REQUEST['email'],
'ip' => $_REQUEST['ip']
);
$hash = pun_hash($edit['pass']);
$db->query(sprintf("INSERT INTO `".$db_prefix."users` (`username`,`password`,`email`,`registered`,`registration_ip`,`last_visit`, `style`)
VALUES ('%s', '%s', '%s', %d, '%s', %d, 'wine')",
$db->escape($edit['name']), $db->escape($hash), $db->escape($edit['mail']), time(), $edit['ip'], time()));
if ($db->affected_rows() == 1)
{
echo "OK: $hash";
}
else
{
echo "ERROR: failed to insert user";
}
?>
[/mono]
В случае успешной регистрации скрипт вернёт hash-код, используемый форумом для пароля пользователя. За счёт этого мы можем не хранить в нашем движке пароль в открытом виде, а хранить лишь hash форума, для того, чтобы "запускать" пользователя на форум.
Скрипт входа на форум:
/forum/interface/login.php?username=...&hash=...&magick_key=...
[mono]
<?php
// request should contain
// magick_key
// username
// hash (password hash)
require_once('mkeys.inc.php');
if (!checkMagickKey($_REQUEST['username'], $_REQUEST['magick_key']))
{
header('Location: ../index.php');
exit();
}
define('PUN_ROOT', '../');
require_once PUN_ROOT.'config.php';
require_once PUN_ROOT.'include/dblayer/common_db.php';
require_once PUN_ROOT.'include/functions.php';
// login
$edit = array(
'hash' => $_REQUEST['hash'],
'name' => $_REQUEST['username'],
);
$id = $db->result($db->query(
sprintf("SELECT id FROM `".$db_prefix."users` WHERE `username` = '%s' AND `password` = '%s'",
$db->escape($edit['name']), $db->escape($edit['hash']))
));
if ($id)
{
pun_setcookie($id, $edit['hash'], time() + 31536000);
}
header('Location: ../index.php');
?>
[/mono]
Скрипт смены пароля:
/forum/interface/change_password.php?username=...&password=...&magick_key=...
[mono]
<?php
// request should contain
// magick_key
// username
// password
require_once('mkeys.inc.php');
if (!checkMagickKey($_REQUEST['username'], $_REQUEST['magick_key']))
{
echo "ERROR: invalid magick key";
exit();
}
define('PUN_ROOT', '../');
require_once PUN_ROOT.'config.php';
require_once PUN_ROOT.'include/dblayer/common_db.php';
require_once PUN_ROOT.'include/functions.php';
// change pwd
$edit = array(
'pass' => $_REQUEST['password'],
'name' => $_REQUEST['username'],
'mail' => '[email protected]',
'ip' => '127.0.0.1'
);
$hash = pun_hash($edit['pass']);
$db->query(sprintf("UPDATE `".$db_prefix."users` SET `password` = '%s' WHERE `username` = '%s'",
$db->escape($hash), $db->escape($edit['name'])));
if ($db->affected_rows() == 1)
{
echo "OK: $hash";
}
else
{
// record not found, insert
$db->query(sprintf("INSERT INTO `".$db_prefix."users` (`username`,`password`,`email`,`registered`,`registration_ip`,`last_visit`, `style`)
VALUES ('%s', '%s', '%s', %d, '%s', %d, 'wine')",
$db->escape($edit['name']), $db->escape($hash), $db->escape($edit['mail']), time(), $edit['ip'], time()));
if ($db->affected_rows() == 1)
{
echo "OK: $hash";
}
else
{
echo "ERROR: failed to update user";
}
}
?>
[/mono]
Если скрипт не найдёт пользователя, он создаст нового.
И, наконец, вспомогательный скрипт для проверки магического ключа:
[mono]
<?php
function checkMagickKey($username, $magickKey)
{
$link = mysql_connect('localhost', 'dbuser', 'dbpassword');
if (!$link)
{
return false;
}
mysql_select_db("integration", $link);
$value = mysql_escape_string(md5($username . $magickKey . "otherkey"));
$rs = mysql_query("SELECT id FROM magick_keys WHERE magick_key = '$value' AND"
." created_at > DATE_SUB(NOW(), INTERVAL 1 MINUTE)", $link);
$row = mysql_fetch_row($rs);
mysql_close($link);
return $row ? true : false;
}
?>
[/mono]
Скрипт подключается к mysql-БД с именем integration, и ищет неустаревший магический ключ в таблице magick_keys.
Вы можете отключить проверку, просто возвращая из данной функции true.
Пример вызова скрипта регистрации из движка на Rails:
(вызывается URL /forum/interface/register.php?username=...&password=...&magick_key=...&email=...&ip=...)
[mono]
def register(username, password, email, ip)
key = Time.now.to_i.to_s
m_key = Digest::MD5.hexdigest(username + key)
magickKey = MagickKey.new(:magick_key => m_key, :created_at => Time.now)
if magickKey.save
Net::HTTP.start(FORUM_SITE) { |http|
resp = http.get2(FORUM_REGISTER_URL + "?username=#{username}&password=#{password}&magick_key=#{key}&email=#{email}&ip=#{ip}")
if resp.code == "200" && resp.body =~ /^OK\:\s(.+)$/
self.password_hash = $1
else
self.password_hash = ""
end
}
end
self.password_hash
end
[/mono]
p.s. php-скрипты написаны благодаря участникам данного форума, и их постам про интеграцию форума с разными системами.
Редактировался andreus (2008-04-16 18:06:55)
Страницы 1
Тема закрыта