Обучение в политехе заключается в сдаче лабораторных работ. Буквально. Очень редко бывает такое, что на парах мы чему-то учимся, зачастую все завязано на самообучении. Грубо говоря, вот вам методичка, разбирайтесь сами, через неделю дедлайн.

В связи с этим мы столкнулись с очередями на сдачу этих лабораторных. Сначала просто писали в общий чат, кто каким будет в очереди (например, "я первый", "я вторая", "я третий" и т.д.). Далее решили создать расшаренную таблицу в гугле для формирования очередей. Однако долго она тоже не прожила, так как со временем появились "умники", которые стали ставить себя первыми в очереди, сдвигая остальных вниз. Потом общий доступ для таблицы закрыли, и было принято решение для записи на сдачу писать старосте, он, в свою очередь, будет добавлять студентов в список. Но староста группы не может быть постоянно на связи, иными словами, оперативно добавиться в очередь было просто невозможно.

В связи с этим я задумался над созданием автоматизированной очереди. В качестве стека основных технологий выбрал HTML5+CSS3 для фронтенда, PHP для бэкенда. В качестве СУБД был выбран MySQL. В первую очередь, конечно, необходимо было продумать структуру базы данных. Предметная область информационной системы уже была сформулирована: "Очередь на сдачу лабораторных работ с возможностью записи по отдельным дисциплинам, удаления своей записи. Учет истории создания записи, удаления записей, включая время записи. Возможность смены пароля, просмотра профиля." Даталогическая модель БД была построена в MySQL Workbench 8.0 CE в нотации IDEF1X.

Даталогическая модель БД в нотации IDEF1X
Даталогическая модель БД в нотации IDEF1X

Небольшое пояснение к даталогической модели:

  1. Сущность students предназначена для хранения списка студентов, содержит следующие поля: имя, фамилия, логин, пароль, дата регистрации, информация об устройстве, с которого производилась регистрация, привилегии (для будущей админки).

  2. Сущность authorization_list предназначена для хранения информации о входе в аккаунт того или иного пользователя (студента), связана внешним ключом с сущностью students, содержит следующие поля: дата авторизации, информация об устройстве, с которого производилась авторизация.

  3. Сущность disciplines предназначена для хранения списка дисциплин (учебных предметов), содержит поле: название дисциплины.

  4. Сущность shared_queue предназначена для формирования очередей, связана внешними ключами с таблицей students и disciplines, содержит поля: дата записи в очередь, статус записи (для хранения истории записей, так называемого, архива).

Далее стоял вопрос с разработкой фронтенда, то есть дизайна будущего проекта. Решил действовать по методике "MinimumCode", подобрал подходящий конструктор, поддерживающий верстку для различных типов девайсов (устройств с различной шириной экрана), который выдает готовый код без лишних наворотов, за исключением рекламной секции в футере, которая убирается простым редактированием HTML-страницы. Проектирование дизайна включало в себя полную проработку структуры проекта, создание различных блоков, которыми будет управлять бэкенд. Таким образом была произведена верстка двух основных страниц: "Главная" и "Профиль". Первая должна включать в себя авторизацию, выбор дисциплины, просмотр очереди и запись в очередь. На второй странице должна отображаться информация о профиле, выход из аккаунта и смена пароля.

Страница "Главная", шапка страницы, блоки авторизации и выбора дисциплины
Страница "Главная", шапка страницы, блоки авторизации и выбора дисциплины
Страница "Главная", блоки очереди и записи в очередь, подвал страницы
Страница "Главная", блоки очереди и записи в очередь, подвал страницы
Страница "Профиль", шапка страницы, блоки профиля и смены пароля
Страница "Профиль", шапка страницы, блоки профиля и смены пароля
Страница "Профиль", блок ограничения доступа, подвал страницы
Страница "Профиль", блок ограничения доступа, подвал страницы

Теперь необходимо объединить всё воедино. То есть написать бэкенд, включая работу с базой данных. Каких-то супер-алгоритмов не придумывал, проект примитивный. Как-будто смысла останавливаться на этом особо нет. Стоит сказать только про хранение ключа сессии в COOKIES, шифрование паролей с использованием 128-битного алгоритма хэширования MD5 (дополнение: очень слабый алгоритм хэширования, который использовать не рекомендуется, на подбор пароля требуется не больше 5 минут), выборку данных из таблиц при помощи SQL-запросов. Ниже приведен фрагмент кода, выполняющий получение названия дисциплины (выборка дисциплины по умолчанию, либо выборка дисциплины, хранящейся в $_GET).

Фрагмент кода, получающего название дисциплины
Фрагмент кода, получающего название дисциплины

Что мы имеем в итоге?

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

Вид страницы "Главная" на мобильном устройстве
Вид страницы "Главная" на мобильном устройстве
Вид страницы "Профиль" на мобильном устройстве
Вид страницы "Профиль" на мобильном устройстве

Над чем необходимо продолжить работу?

Конечно, в ближайшем будущем планируется ввести привилегии пользователей, иными словами, админку для определенных пользователей. В которой необходимо реализовать возможность добавления студентов в любое место в очереди для любой дисциплины, удаление любых записей, смену паролей для каждого студента, просмотр архива очереди, закрытие и открытие записи на какую-либо дисциплину.

Комментарии (13)


  1. FanatPHP
    09.04.2024 13:27
    +9

    Все это хорошо, только непонятно, зачем было делать авторизацию, если все пароли можно украсть через SQL-инъекцию, а на взлом среднего пароля, "зашифрованного" с использованием 128-битного алгоритма хэширования MD5 требуется несколько минут. Или же украсть куки из браузера через XSS. Или же авторизоваться без пароля через ту же SQL инъекцию.

    Было бы неплохо, если бы вы сделали работу над ошибками, ознакомившись с самыми базовыми правилами веб-разработки (и парой мелких замечаний):

    • хэширование паролей должно делаться только с использованием специально предназначенной функции

    • любые данные передаются в SQL запрос не напрямую, а через символы подстановки

    • Любой вывод должен начинаться после того, как закончилось получение и обработка данных

    • При выводе в HTML все переменные должны экранироваться с помощью htmlspecialchars()

    • phpMyAdmin - это не СУБД. СУБД, с которой вы работаете, называется по-другому

    • кодировку соединения с БД устанавливают один раз после установления соединения, а не после каждого запроса

    Впрочем, вы с этим быстро разберетесь, а вот то что у вас появилась такая идея, и вы довели её до воплощения - это очень хорошо.


    1. samokhvaloff Автор
      09.04.2024 13:27

      Спасибо за ваш комментарий. Действительно, в статье допустил ошибку phpMyAdmin - это не СУБД. Также согласен со всеми остальными указанными замечаниями, постараюсь исправить.

      Алгоритм хэширования использовал исключительно в целях хоть какой-то, пусть и "мнимой", безопасности, дабы не возникло банального желания у пользователя с этим разбираться. Подбирать пароли для каждого пользователя, которого хочется сдвинуть в очереди, звучит всяко сложнее, чем просто выделить ячейки в гугл-таблице.

      В остальном же, как отвечал уже в комментариях, на реализацию ушел 1 рабочий день (может чуть больше, если считать заполнение БД и другие факторы). Проект используется только одной учебной группой, не заморачивался сильно. Поэтому прошу сильно не пинать за такие грубые ошибки.


      1. FanatPHP
        09.04.2024 13:27
        +1

        А кто вас пинает-то? Вас наоборот поддержали, не стали минусовать.
        При том что статья откровенно слабая, и обычно за такие тут закидывают тухлыми помидорами. Но вас никто не пинал, просто написали что и как исправить. Но внезапно вместо того, чтобы потратить 2 часа на исправление, или хотя бы задать вопросы о том, как сделать лучше, вы зачем-то решили начать оправдываться.

        При том что как раз оправданий ваших никто не просил, и они тут никому не интересны. А вот вы начинаете выглядеть гораздо глупее, признав только одну дурацкую ошибку, а по остальным начав оправдываться!

        Какая разница, сколько дней у вас ушло? К чему здесь это "использует одна группа" и "мнимая безопасность"? Как будто если бы использовала не одна группа, а две, то вы бы сделали по-другому? Или вы хотите сказать, что знаете про нормальное хэширование, но сознательно выбрали "128-битный алгоритм", не преминув об этом написать? Нет? А к чему тогда это всё написано?

        Вы сейчас этим одним этим комментарием растеряли весь кредит поддержки, который вам дало сообщество. Вы, наверное, не поняли главное. Что статья на самом деле не подходит для Хабра вообще. В первую очередь форматом "Смотрите какой я молодец, на коленке сделал приблуду для студентов!", в то время как на Хабр пишут "Смотрите, что нового вы можете узнать".


        1. samokhvaloff Автор
          09.04.2024 13:27

          Не понимаю смысла данного комментария.

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

          По-моему я написал, что услышал все замечания и буду стараться исправить. Даже поблагодарил вас за то, что вы проанализировали статью и указали на ошибки. Они действительно были совершены, это я признаю. И где я оправдываюсь?

          Какая разница, сколько дней у вас ушло? К чему здесь это "использует одна группа" и "мнимая безопасность"?

          Потому что данное решение нужно было "здесь и сейчас". И ключевым фактором при реализации была, в первую очередь, скорость. Была необходимость как можно быстрее ввести продукт в эксплуатацию, а потом уже закрывать все уязвимости и как-то улучшать.

          Что статья на самом деле не подходит для Хабра вообще. В первую очередь форматом "Смотрите какой я молодец, на коленке сделал приблуду для студентов!", в то время как на Хабр пишут "Смотрите, что нового вы можете узнать".

          Кроме того, делать поспешные выводы о цели написания данной статьи абсолютно некорректно с вашей стороны. Цели каким-то образом восхвалить себя при помощи этой статьи я не имею. Она была опубликована из-за самой идеи проекта и для получения обратной связи, касательно моей реализации этой идеи. Я хотел узнать об ошибках в проекте, получить адекватную критику и услышать новые идеи и предложения. Всё сказанное в комментариях, без исключения, было принято во внимание.


  1. kubk
    09.04.2024 13:27
    +2

    Думаю, что раз нашлись умники, которые стали ставить себя первыми в очереди, то найдутся и умники, которые через SQL-инъекции в коде получат доступ к БД и будут продолжать ставить себя на первое место. Автору рекомендую ознакомится с основами веб-безопасности раз в универе этому не учат. Статья как будто пятнадцатилетней давности - $_GET параметры передаются напрямую в запрос, MD5 пароли которые подбираются по радужным таблицам, вёрстка на clearfix'ах и смешивание слоёв логики и отображения.


  1. baldr
    09.04.2024 13:27
    +1

    Ну вот и сколько времени вы потратили на эту задачу? Неделю? Три недели?

    Сначала просто писали в общий чат, кто каким будет в очереди (например, "я первый", "я вторая", "я третий" и т.д.)

    Вот чем этот вариант был плох? Для 20 человек раз в неделю так сложно в чате договориться? Создайте 10 чатов если надо, для каждого предмета. Быстро, дешево, просто. На работе вам тимлид так и скажет, что нечего ерундой в рабочее время заниматься.

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

    Вроде сессия ещё не скоро.. Надо ждать нового наплыва лабораторок на хабре?


    1. samokhvaloff Автор
      09.04.2024 13:27

      Ну вот и сколько времени вы потратили на эту задачу? Неделю? Три недели?

      Данный проект был написан "на коленках" за 1 день.

      Цели продвинуть себя в очереди вперед не имею. Создавать отдельные чаты для каждой дисциплины? Вы серьезно сейчас? В принципе, практика с чатами уже была и оказалась абсолютно безуспешной. Как минимум, нельзя отследить текущее состояние очереди. В случае же с автоматизированной очередью, каждый студент после защиты лабораторной работы должен удалить свою запись.


  1. kalbas
    09.04.2024 13:27

    В качестве СУБД был выбран phpMyAdmin

    И сразу 2 балла. На пересдачу.


    1. samokhvaloff Автор
      09.04.2024 13:27

      В статье действительно опечатка: phpMyAdmin - не СУБД


  1. alexalok
    09.04.2024 13:27

    Автор, Вы молодец! От всего сердца советую только одно - не принимайте близко к сердцу то, что другие пишут о том, что код кривой и сейчас так не пишут. Успешные проекты, которые мы видим вокруг и которыми пользуемся каждый день, начинались так же, если не хуже. Продолжайте развивать свои навыки, и помните, что всегда найдется тот, кто скажет "х***я [фигня], переделывай".


    1. FanatPHP
      09.04.2024 13:27
      +1

      Я не очень понял логику этого комментария. Так надо автору развивать свои навыки, или не надо? Если надо, то в чем проблема прислушаться к рекомендациям? И как вы ему предлагаете развивать свои навыки, если не переделкой кода и исправлением ошибок? И в чем, собственно, проблема переделать?


      1. alexalok
        09.04.2024 13:27

        Так я вроде про навыки и написал, что развивать надо. И что к комментариям нужно относиться критически и никогда не воспринимать написанное в них (да и в целом в интернете, в учебниках и т.д.) как прописную истину.


  1. kolabaister
    09.04.2024 13:27

    А почему не подошли гугл формы? Ответ в форме всегда добавляет в конец списка. Таблицу с результатами можно или вовсе не выкладывать или выложить в общий доступ в режиме чтения. Ну или брать данные из нее и выводить в любой удобной форме.