простая авторизация Php Mysql

  • Автор темы Kauperwood
  • Дата начала
Статус
Закрыто для дальнейших ответов.
K

Kauperwood

Гость
#1
исходя из существующего руководства чтобы не теряться в кавычках допилил файлы изменив способ вывода ошибок.
БД
Код:
CREATE TABLE users (
id mediumint(9) NOT NULL AUTO_INCREMENT,
login varchar(32) NOT NULL DEFAULT 'CREATE UNIQUE INDEX',
pass varchar(32) NOT NULL DEFAULT 'NOT NULL',
email varchar(64) NOT NULL DEFAULT 'CREATE UNIQUE INDEX ',
`status` tinyint(2) DEFAULT NULL,
`timestamp` int(10) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM;
файл для регистрационной формы (проверяет ошибки в форме и отправляет письмо с кодом активации):
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">registration.php</div></div><div class="sp-body"><div class="sp-content">
Код:
<?php
session_start(); 
$host = "host"; // хост
$user = "whoisthis"; // пользователь
$pass = "1234"; // пароль
$db = "ok_db"; // наша БД
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$rLogin = trim($_POST['rLogin']);
$rPass = trim($_POST['rPass']);
$rPass2 = trim($_POST['rPass2']);
$rEmail = trim($_POST['rEmail']);
$captha1 = $_POST['captcha'];
$mdPassword = md5($rPass);
$time = time();
// Устанавливаем соединение с бд(не забудьте подставить ваши значения сервер-логин-пароль)
$link = mysql_connect($host, $user, $pass);

$errore='';

if ($rLogin == '') $errore .= "Поле 'Логин' не заполнено<br />\n";
// Логин может состоять из букв, цифр и подчеркивания
if (!preg_match("/^\w{3,}$/", $rLogin)) $errore .="В поле 'Логин' введены недопустимые символы<br />\n";
if ($rEmail == '') $errore .= "Поле 'E-mail' не заполнено<br />\n";
// Проверяем e-mail на корректность
if (!preg_match("/^[a-zA-Z0-9_\.\-]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,6}$/", $rEmail)) $errore .= "Указанный 'E-mail' имеет недопустимый формат<br />\n";

if ($rPass == '' || $rPass2 == '') $errore .= "Поле 'Пароль' не заполнено<br />\n";
if ($rPass !== $rPass2) $errore .= "Поля 'Пароль' и 'Повтор пароля' не совпадают<br />\n";
// Пароль не может состоять из букв, цифр и подчеркивания
if (!preg_match("/^\w{3,}$/", $rPass)) $errore .= "В поле 'Пароль' введены недопустимые символы<br />\n";
if (!$captha1) $errore.="не введен защитный код!<br>"; 
if ($captha1 != $_SESSION['cap_code']) $errore.="не корректный защитный код!<br>";  
// В базе данных у нас будет храниться md5-хеш пароля

if (!$link) $errore .= "Не могу соединиться с базой данных";
header('Content-Type: text/html; charset= utf-8');
echo "<b style='color:red;'>$errore</b><br>"; 

if (!$errore) { 
$mysqlerr ="";
mysql_select_db('okrasim_db', $link);

$cheklogin = mysql_query("SELECT * FROM users WHERE login = '".$rLogin."'",$link);
$chekmail = mysql_query("SELECT * FROM users WHERE email = '".$rEmail."'",$link);
if (mysql_num_rows($cheklogin)>0) $mysqlerr .= "Такое имя уже используеться<br />\n";
if (mysql_num_rows($chekmail)>0) $mysqlerr .= "Такой емануил занят<br />\n";

header('Content-Type: text/html; charset= utf-8');
echo "<b style='color:blue;'>$mysqlerr</b><br>"; 

if (!$mysqlerr) { 

mysql_query("INSERT INTO users (login, pass, email, timestamp)
VALUES ('$rLogin','$mdPassword','$rEmail',$time)",$link);
header('Content-Type: text/html; charset= utf-8');
echo "Пользователь добавлен<br />\n";

// Получаем Id, под которым юзер добавился в базу
$id = mysql_result(mysql_query("SELECT LAST_INSERT_ID()", $link), 0);
// Составляем "keystring" для активации
$key = md5(substr($rEmail, 0 ,2).$id.substr($rLogin, 0 ,2));
$date = date("d.m.Y",$time);


// Компонуем письмо
$subject = 'Подтверждение регистрации на сайте ';
$letter = <<< LTR
Здравствуйте!
Ваши регистрационные данные:
логин: $rLogin
пароль: $rPass

Для активации аккаунта вам следует пройти по ссылке:
http://sayta.net/activation.php?login=$rLogin&key=$key //запрос обработает файл активации
Данная ссылка будет доступна в течении 5 дней.
$date
LTR;
// Отправляем письмо
if (!mail($rEmail, $subject, $letter, "Content-Type: text/plain; charset=utf-8\r\n\r\n".$headers)) {
// Если письмо не отправилось, удаляем юзера из базы
mysql_query("DELETE FROM users WHERE login='".$login."' LIMIT 1", $link);
header('Content-Type: text/html; charset= utf-8');
echo 'Произошла ошибка при отправке письма. Попробуйте зарегистрироваться еще раз.';
}
else {
header('Content-Type: text/html; charset= utf-8');
echo 'Вы успешно зарегистрировались в системе. На указанный вами
e-mail было отправлено письмо со ссылкой для активации аккаунта.
У вас 5 дней!';
header('Refresh: 3; URL=index.php');
}
mysql_close($link);

} //$mysqlerr
}//$errore
}//$_SERVER['REQUEST_METHOD'] == 'POST'
?>
файл активации пользователя:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">activation.php</div></div><div class="sp-body"><div class="sp-content">
Код:
<?php
if (isset($_GET['login']) && isset($_GET['key'])) {
$login = $_GET['login'];
$key = $_GET['key'];

$activationerror = "";

// Делаем проверку login на нехорошие символы
if (!preg_match("/^\w{3,}$/", $login)) $activationerror .="Неправильная ссылка!<br>";

$time = time();
$link = mysql_connect('host','user','password');
if (!$link) {
$activationerror .= "Не удалось соединиться с БД!<br>"; mysql_close($link);
}

mysql_select_db('okrasim_db', $link);
$res = mysql_query("SELECT id, email, status, timestamp
FROM users WHERE login='$login' LIMIT 1", $link);
// Есть ли пользователь с таким логином?
if (mysql_num_rows($res) != 1) {
$activationerror .="Такого пользователя нет!<br>"; mysql_close($link);
} 
$user = mysql_fetch_row($res);
// Может он уже активен?
if ($user[2] == 1) {
$activationerror .="Данный логин уже подтвержден!<br>"; mysql_close($link);
}
// Успел ли юзер активировать логин? (если нет - удаляем из базы)
if ($user[3] - $time > 5*24*60*60) {
mysql_query("DELETE FROM users WHERE login='$login' LIMIT 1", $link);
$activationerror .="Срок активации истёк! Регистрируйтесь заново!<br>";mysql_close($link);
}
$key1 = md5(substr($user[1], 0 ,2).$user[0].substr($login, 0 ,2));
// Проверяем "keystring"
if ($key1 != $key) {
$activationerror .="Неправильная контрольная сумма!"; mysql_close($link);
}
echo "<b style='color:green;'>".$activationerror."</b><br>";
if (!$err) {
// Если все проверки пройдены - активируем логин!

mysql_query("UPDATE users SET status = 1 WHERE login='$login'", $link);
echo "Ок вы зарегистрированы!";
mysql_close($link);
}

}
?>
файл авторизации:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">login.php</div></div><div class="sp-body"><div class="sp-content">
Код:
<?php
if (isset($_POST['login'])) {
$passwordHash = md5($_POST['password']);
$login = $_POST['login']; 

$loginerr="";
// Проверка логина на плохие смиволы
if (!preg_match("/^\w{3,}$/", $login)) $loginerr .="Неправильный логин!";
$link = mysql_connect('host','user','password');
if (!$link) $loginerr .="Не удалось соединиться с БД";
mysql_select_db('db', $link);
$res = mysql_query("SELECT status FROM users WHERE login='$login'AND pass='$passwordHash'", $link);
// Есть ли пользователь с таким логином?
if (mysql_num_rows($res) < 1) { 
$loginerr.="Такого пользователя нет, или пароль не верный!";mysql_close($link);
}
// Какой статус у пользователя?
if (mysql_result($res, 0) != 1) {
$loginerr.="Логин не активирован!";  
mysql_close($link);
}

header('Content-Type: text/html; charset= utf-8');
echo "<b style='color:grey;'>$loginerr</b><br>"; 
if(!$loginerr) {
// Стартуем сессию и записываем логин в суперглобальный массив $_SESSION
session_start();
$_SESSION['user'] = $login;
mysql_close($link);
// Если определена страница с которой мы пришли,
// на нее и переадресуем, либо на главную
if (isset($_SERVER['HTTP_REFERER'])) {
header ("location: ".$_SERVER['HTTP_REFERER']);
}
else {
header ("location: index.php");
}
}	
}
?>
и еще чуть не забыл файл для выхода
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">logout.php</div></div><div class="sp-body"><div class="sp-content">
Код:
<?
session_start();
if (isset($_SESSION['user'])) {
// удаляем элемент "user"
unset($_SESSION['user']);
}
if (isset($_SERVER['HTTP_REFERER'])) {
header ("location: ".$_SERVER['HTTP_REFERER']);
}else {
header ("location: index.php");
}
?>
и две формы ввода данных
первая для регистрации:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">registration_form.php</div></div><div class="sp-body"><div class="sp-content">
Код:
<form action="registration.php" method="post">
<table>
<tr>
<td>Логин* :</td>
<td><input type="text" name="rLogin" value="" size="25" maxlength="30" /></td>
</tr>
<tr>
<td>Пароль* :</td>
<td><input type="password" name="rPass" value="" size="25" maxlength="30" /></td>
</tr>
<tr>
<td>Повторите пароль* :</td>
<td><input type="password" name="rPass2" value="" size="25" maxlength="30" /></td>
</tr>
<tr>
<td>E-mail* :</td>
<td><input type="text" name="rEmail" value="" size="25" maxlength="30" /></td>
</tr>
<tr>
<td>Captcha* :</td>
<td><img id="cap" src="capa.php"/><input class="capcode" type="text" name="captcha" /></td>
</tr>
<tr>

<td></td>
<td><input type="reset" name="reset" value="Очистить" />
<input type="submit" name="ok" value="Готово" /></td>
</tr>
</table>
</form>
и вторая для логина та что должна быть вставлена в корневой файл:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">index.php</div></div><div class="sp-body"><div class="sp-content">
Код:
<?
session_start();
if (isset($_SESSION['user'])) {
$auth = "Привет ".$_SESSION['user']."!<br />\n";
$auth .= "<a href='logout.php'>Выйти</a>";
$docum = "Эта информация только для зарегистрированных";
}else {
$auth = <<< AUTH
<form method="post" action="login.php">
<table>
<tr>
<td>Логин</td>
<td><input type="text" name="login"></td>
</tr>
<tr>
<td>Пароль</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Войти"></td>
</tr>
</table>
</form>
AUTH;
$docum = "Эта общая информация";
}
?>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>авторизация</title>
</head>
<body>
<? echo $auth; ?>
<hr />
<? echo $docum; ?>

<br>
<a href="reg_form.php">регистрация</a>
</body>
</html>
без реализации кук!
что мог проверил, должно работать!
может кому то пригодиться, прикрепил архивом все файлы + моя мини-капча.

Чего пишу то, хотел бы поинтересоваться каким образом это все сломать, или что можно предпринять что бы стало безопаснее, и тому подобное.
 

Вложения

09.11.2009
665
1
#2
У себя запустить не удалось, поскольку :) .
Может плохо искал, но не нашол проверку логина, пароля... на наличие кавычек, как одинарных ' ` так и двойных ".
 
K

Kauperwood

Гость
#3
У себя запустить не удалось
там только возможны бока где не проставили ваши адреса, пароли, и тому подобное... в средине файлов есть select_db там тоже может (говно-код как никак :))
конечно все возможно, но знаю что работало)
Может плохо искал, но не нашол проверку логина, пароля... на наличие кавычек, как одинарных ' ` так и двойных ".
не имеется, это правда, а также ограничений по длинне слов, емеилов, отзывов - хорошо хоть это можно быстро сделать.

да и после регистрации когда очередь логинится вообще не было проверки пароля - заходи не печалься), посоветовали добавить /// AND pass='$passwordHash'" ///
"$res = mysql_query("SELECT status FROM users WHERE login='$login'AND pass='$passwordHash'", $link);" в login.php.
Вообще скрипт одновременно ругается что "Такого пользователя нет, или пароль не верный" + Логин не активирован! - ну с паролем понятно, так как вообще нет отдельной проверки пароля, а вот "Логин не активирован!" напрягает назойливостью.
 

vital

Больной Компом Детектед
29.01.2006
2 432
42
#4
1. Ломается как угодно - SQL injection, XSS. Если бы были куки - наверняка и CSRF.
2. Не понятные буквы выше - гуглить.
3. Читайте про CMF, MVC, Route. Так как сделали вы делать нельзя.
4. см.2.

А потом с вопросами велкам)
 
K

Kauperwood

Гость
#5
по пункту 2, поправлю, Вы хотели сказать про сокращения))
не сразу уловил)
 
K

Kauperwood

Гость
#6
Так как сделали вы делать нельзя.
делал только вывод ошибок в одну переменную, вместо "or die" так как напрягает каждый раз писать "header('Content-Type: text/html; charset= utf-8');".
Почти все остальное из руководства .
это не будет критично?
 

vital

Больной Компом Детектед
29.01.2006
2 432
42
#7
Учитывая, что это надо переписать целиком, уж простите, нет, это не будет критично.
 
K

Kauperwood

Гость
#8
Учитывая, что это надо переписать целиком, уж простите, нет, это не будет критично.
возможно хочу попробовать,
тогда, пытаться переписать get как массив функций, взять уже написанные(рекомендуемые), связать их вместе. - норм будет?
или может второй вариант, сразу на фреймворк но это ж лес поначалу, справочник новый и тому иное.

PS. видимо плохо искал но хорошую статью-руководство хочется с названием "Когда и с чего начать изучение Zend".))
 

vital

Больной Компом Детектед
29.01.2006
2 432
42
#9
сразу на фреймворк но это ж лес поначалу, справочник новый и тому иное.
Можно и без фреймворка. Что мешает сделать роуты и паттерн MVC руками? Хотя, наверно, с нуля это тяжело по началу. ЛУчше фреймворк, что бы понять.
А по зенду..
У вас как с английским? Я не знаю честно говоря, что вам посоветовать почитать для начала. Но есть хорошие видеоуроки по зенду, рассчитанные на не знание фреймворка вообще. На английском, офк.
 
K

Kauperwood

Гость
#10
c EN более менее, уроки - это на zendcasts или другие?
 

vital

Больной Компом Детектед
29.01.2006
2 432
42
#11
Есть зендкастс, и есть еще от одного автора.. посмотрю позже чуть.
 
K

Kauperwood

Гость
#12
Vital вы сказали что так делать нельзя (авторизация), и теперь я в тупике. Реально сам не напишу авторизацию. Если не сложно можете посоветовать что нибудь из категории " обычных процедурных подходов"? для начала ведь хоть что то нужно сделать, а если то нельзя и другое нельзя, как быть то, надо этот опыт ведь как то получить. Эта авторизация мне хоть и не нравится, но она хоть работала у меня. Может исходя из нее какие то замечания или может где то в сети есть пример получше или информация?
 
Статус
Закрыто для дальнейших ответов.