Sign In на чистом PHP

Тема в разделе "Как сделать...", создана пользователем sasha_ua, 8 июн 2014.

  1. sasha_ua

    sasha_ua Постоялец

    Регистр.:
    23 июн 2010
    Сообщения:
    66
    Симпатии:
    0
    Здравствуйте.

    Написал простую активацию на ПХП но есть 2 проблемы:

    1. Как запретить доступ ко всему кроме index.php, т.е. чтобы нельзя было ввести site/admin.php
    Пробовал запрещать в .htaccess но тогда доступ через скрипты тоже закрыт, например admin.php выступает как обработчик формы в index.php и соответственно при вызове будет ошибка.
    Код:
    RewriteEngine on
    
    RewriteCond%{REQUEST_FILENAME}!-f
    
    RewriteCond%{REQUEST_FILENAME}!-d
    
    RewriteRule^([^?]*)$ /index.php?path=$1 [NC,L,QSA]
    
    Не помогло.

    2. Как сделать так чтобы поля login/password не запоминали значений(картинка в приложении)?
    autocomplete="off" не помог

    Задача активации дать доступ к странице admin.php

    Вот код:

    index.php
    Код:
    <?php 
    
    require_once('functions.php');
    
    // while (@ob_end_flush());
    
    do_html_header();
    
    display_login_form();
    
    do_html_footer(); 
    
    ?>
    
    admin.php
    Код:
    <?php 
    
    require_once('functions.php');
    
    session_start();
    
    // Создать короткие имена переменных
    $username = $_POST['username'];
    $passwd = $_POST['passwd'];
    
    if ($username && $passwd) {
    // Пользователь только что попытался войти в систему
      try {
        login($username, $passwd);
        // Если пользователь записан в базе данных, 
        // зарегистрировать его идентификатор
        $_SESSION['valid_user'] = $username;
      }
      catch (Exception $e) {
        // Неудачный вход в систему
        do_html_header('Проблема:');
        echo 'Вход в систему невозможен. '
             .'Для просмотра этой страница необходимо войти в систему.';
        do_html_url('index.php', 'Вход');
    
        exit;
      }      
    }
    
    do_html_header();
    check_valid_user();
    
    // Пишем все что нам нужно от админки
    
    
    
    $_SESSION['valid_user'] == 0;
    session_destroy();
    
    do_html_footer(); 
    ?>
    
    functions.php
    Код:
    <?php 
    
    function display_login_form() {
    ?>
        <form method="post" action="admin.php" class="login-form">
            <ul>
                <li>
                    <label for="username">Login</label>
                    <input type="text" id="username" name="username" autocomplete="off">
                </li>
                <li>
                    <label for="passwd">Password</label>
                    <input type="password" id="passwd" name="passwd" autocomplete="off">               
                </li>
                <li><input id="submit-btn" type="submit" value="Вход"></li>
            </ul>
        </form>
    <?php
    }
    
    function db_connect() {
      $result = new mysqli("localhost", "root", "", "portfolio"); 
      if (!$result)
        throw new Exception('Невозможно подключиться к серверу баз данных');
      else
        return $result;
    }
    
    function do_html_header($title="") {
    ?>
        <!DOCTYPE html>
    
        <html>
        <head>
            <title><?php echo $title;?></title>
            <meta http-equiv="content-type" content="text/html; charset=utf-8" />
            <style media="all" type="text/css">@import "css/style.css";</style>
            <link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,700,300italic&subset=latin,cyrillic' rel='stylesheet' type='text/css'>
        </head>
        <body>
        <div class="container">
    <?php
      if($title)
        do_html_heading($title);
    }
    
    function do_html_heading($heading) {
      // Вывести верхний колонтитул HTML
    ?>
      <h2><?php echo $heading; ?></h2>
    <?php
    }
    
    function do_html_footer() {
    ?>
      </div>
      </body>
      </html>
    <?php
    }
    
    function do_html_URL($url, $name) {
      // Вывести URL-адрес в виде ссылки и дескриптор новой строки
    ?>
      <br /><a href="<?php echo $url;?>"><?php echo $name;?></a><br />
    <?php
    }
    
    function check_valid_user() {
      // Определяет, вошел ли пользователь в систему и, 
      // если нет, выводит соответствующее уведомление
    
      global $valid_user;
      if (isset($_SESSION['valid_user'])) {
        echo 'Вы вошли в систему под именем '
          .stripslashes($_SESSION['valid_user']).'.';
        echo "<br />";
      } else {
        // Пользователь не вошел в систему
        do_html_heading("Проблема:");
        echo "Вы не вошли в систему.<br />";
        do_html_url('index.php', 'Вход');
        exit;
      }
    }
    
    function login($username, $password) {
      // Проверяет наличие имени пользователя и пароля в базе данных.
      // Если они там содержатся, возвращается значение true, 
      // в противном случае генерируется исключение.
    
      // Подключиться к базе данных
      $conn = db_connect();
    
      // Проверить уникальность имени пользователя
      $result = $conn->query("select * from user
                where username='$username' and passwd = md5('$password')");
      if (!$result)
        throw new Exception('Вход в систему невозможен');
    
      if ($result->num_rows > 0)
        return true;
      else
        throw new Exception('Вход в систему невозможен');
    }
    ?>
    
     

    Вложения:

    • login.jpg
      login.jpg
      Размер файла:
      15,6 КБ
      Просмотров:
      17
  2. Denixxx

    Denixxx

    Регистр.:
    7 фев 2014
    Сообщения:
    247
    Симпатии:
    191
    А не проще переименовать админку?
     
  3. sasha_ua

    sasha_ua Постоялец

    Регистр.:
    23 июн 2010
    Сообщения:
    66
    Симпатии:
    0
    Смысл не в именовании, хочется сделать правильно, чтобы не было доступа ни к чему кроме index.php.

    Мне подсказывают что .htaccess не подходит для моего случая, что нужно в начале каждого файла проверять залогинен пользователь или нет и в зависимости от этого выдавать страницу или нет.
    Вот пример есть форма у нее action="handler.php", если я напишу в браузере site/handler.php браузер его запустит, это не правильно..
    Или если мне нужно при нажатии на какой-то элемент например ссылка, перекинуть пользователя на другую страницу, например <a href="login.php">Войти</a>, опять же можно запустить site/login.php

    Может кто-то в курсе как это сделано в wordpress например?
     
  4. Denixxx

    Denixxx

    Регистр.:
    7 фев 2014
    Сообщения:
    247
    Симпатии:
    191
    Если пользователь залогинен и он админ — в панели пользователя показываем ссылку на админку.
    Но проблема в том, что админка в движках обычно находится по одному и тому же адресу.
    А значит — зная где админка, злоумышленник может применить брутфорс.
    Ни в каких вордпрессах/джумлах эта проблема не решается.
    В результате периодически наблюдаются взломы движков по принципу подбору пароля.
    Я впрочем в движке, который развиваю, недавно решил эту проблему:
    http://reloadcms.com/main/?module=forum&action=topic&id=174&pid=25#25
    Решил именно тем, что сделал переименование админки.
    Но это я, ведь у меня кроме бесплатной разработки более 20 платных клиентов, и я заинтересован в своём спокойствии;)
    Потому что для разработки сайтов чужих поделий уже давно не использую.
    Собственно, решение сделано недавно, потому что о взломах уже года 3 не слышал — слишком успокоился:)
     
    linpc нравится это.
  5. Gang

    Gang Создатель

    Регистр.:
    28 янв 2013
    Сообщения:
    21
    Симпатии:
    9
    К примеру в начале каждого php-файла, который нужно закрыть, добавить проверку на существования одной из функций, которой в этом файле нет:
    PHP:
    if ( !function_exists'some_function' ) ) {
        echo 
    'Hello, hacker';
        exit;
    }
     
  6. linpc

    linpc

    Регистр.:
    6 апр 2012
    Сообщения:
    178
    Симпатии:
    52
    Как тебе сказали, переименуй проверку, и при вводе не правильного пароля несколько раз блокируй Апи на сутки. Допустим. Иногда сидеть сутки и ждать когда брут сбрутит пароль какой нибудь надоедает.
     
  7. DevOrc

    DevOrc Создатель

    Регистр.:
    5 июн 2014
    Сообщения:
    31
    Симпатии:
    10
    Все верно, защита на уровне "неизвестных данных" это не метод, все тайное становится явным,
    - во первых можно сделать антибрут на 2-3 попытки а дальше фриз, скажем на час,
    - во вторых, тупо доступ по определенному ip или сигнатуре браузера, прописав там произвольный юзерагент.
    - также, весьма желательно отделать пользовательскую сессию от админской, что бы просто не увели).
     
  8. Denixxx

    Denixxx

    Регистр.:
    7 фев 2014
    Сообщения:
    247
    Симпатии:
    191
    - во-первых, потеряете 80% пользователей, которым не понравится эта фича
    - во-вторых, доступ по ip & браузеру — это чушь. Ибо ip в 80% случаев не статичен, а браузеры обновляются, меняя юзерагент.
    - в третьих, что значит отделять сессию? Вот в этом пожалуйста подробнее.
    Зы: простое переименование admin.php -> hjk13mk3ckjf9057klkcfd_23!6dsk.php при этом позволит спать спокойно.
    Но это ж некрасиво, да... Поэтому будем банить по IP и браузеру, пока совсем у нас пользователей не осталось.
    А Вы не думали — может пользователь хотел коммент в статью написать, или тему на форуме — спросить чо.
    А его — бан по IP! И нечего тут.

    Совет: ищите простые решения, которые не создают трудностей для посетителей. Сюрприз: сайт без посетителей — бесполезен!
     
    Последнее редактирование: 9 июн 2014
  9. UJy

    UJy

    Регистр.:
    23 авг 2011
    Сообщения:
    338
    Симпатии:
    121
    А нельзя ли в functions.php при отправке формы генерировать переменную со случайным значением, затем создать сессию с названием, которое равняется этой сгенерированной переменной, переменную отправлять вместе с формой в admin.php. В админ.пхп перед выполнением всех функцию сделать проверку на существование сессии с именем переданной переменной, если существует - обрабатываем запрос дальше, если не существует - возвращаем обратно на index.php.
    Если обратиться напрямую к admin.php - сессии и переменной не будет - посетителя завернет на индекс...