Веб-программирование (программа курса)
Аннотация
Курс посвящен созданию веб-приложений. На курсе участники научатся работать с html/css/javascript, динамически генерировать страницы при помощи языка python и пользоваться базами данных и многое узнают про то, как работает интернет.
В процессе работы мы создадим сайт для редактирования презентаций и каждый сможет добавить к нему те функции, которые посчитает нужным.
Первые несколько занятий могут посещать все, на более поздних занятиях вам потребуется умение программировать (желательно на python, но если вы знаете любой другой язык, то тоже справитесь).
План
Общая идея курса заключается в том, чтобы взять библиотеку reveal.js для отображения презентаций и на его основе создать веб-сайт для редактирования презентаций. За счёт использования библиотеки мы можем сразу сделать полезный html-документ, который будет отображаться как презентация - и на его примере познакомимся и с разметкой, и с классами элементов, и со стилями (подключим разные темы и добавим свои модификации). Так школьники сначала делают презентацию в формате статического html, а потом потихоньку начинают её менять на динамическую.
Пока что я предполагаю в качестве веб-сервера взять минималистичный BottlePy, но возможно, что в процессе мы перейдем на что-то более серьезное или мейнстримное (flask/django). В процессе возникнут задачи сохранения работы (тут мы поговорим про базы данных), авторизации (это повод поговорить совсем немного про криптографию) и обновления данных без перезагрузки страницы (чтобы поговорить про AJAX). Где-то в середине работы разберемся с тем как разместить сайт в сети.
Распределение по занятиям условное. С большой вероятностью занятия займут больше времени, чем два академических часа.
Занятие 1
Заходим на github и скачиваем reveal.js. Немного говорим о том, что такое гитхаб и что такое git (пока без подробностей). Заглядываем в структуру файлов библиотеки. Разбираемся, чем отличаются html, js, css. Открываем пример и смотрим, как к нему подключены скрипты и стили, меняем подключенную тему. Копипастом добавляем слайд. Где-то в процессе, вероятно, устанавливаем на компьютеры git и sublime text (если это можно сделать заранее, будет замечательно). Разбираемся с html. Добавляем ещё несколько слайдов: с заголовками, абзацами итп. Открываем в браузере (в идеале у всех должен работать chrome или хотя бы на одном и том же браузере) инспектор и смотрим на дерево тэгов, на их свойства, пробуем менять прямо в браузере.
Занятие 2
Смотрим на слово class. Добавляем тэгом несколько разных классов - смотрим, что меняется. Дальше они получают задание сделать презентацию, в которой надписи появляются и исчезают, меняют цвет итд. Школьники отправляются читать документацию - и искать нужные значения классов. При необходимости учатся читать через google translate. Добавляем в css свой класс для текста комик-сансом в рамочке и элементы в презентацию, которые так оформляются. Добавляем в презентацию пару картинок.
Переходим в инспекторе на вкладку “сети” и смотрим, сколько запросов отправил браузер, чтобы отобразить картинку. Говорим про то, что по адресу сайта расположена обычно только html-страница, и её можно посмотреть при помощи других инструментов (если занятие идёт бодро, можно взять curl и научиться делать запросы из командной строки и чуть-чуть обсудить http), а браузер вытаскивает стили-скрипты-картинки-шрифты и самостоятельно делает вспомогательные запросы. Говорим, что значит “почистить кэш”. Тут же можно обсудить коды состояний: перенаправления, ошибки итп.
Занятие 3
Делаем три немного разные презентации. Каждой презентации добавляем сверху менюшку со ссылками на остальные презентации. Теперь у нас есть сайт с несколькими страничками. Кратенько говорим про index.html (и создаем какой-нибудь простенький).
Менюшку сверху переносим вбок. Говорим про систему display: block/inline-block/inline. В боковой менюшке каждую ссылку снабжаем картинкой, названием, датой, автором - так, чтобы пришлось сделать раскладку каждой такой ссылки на части в одной строке/в разных строках. С помощью классов оформляем отдельные элементы этих элементов менюшки. В процессе немного обсуждаем css-селекторы.
Занятие 4
Подключаем к проекту jquery, не скачивая его (обсуждаем CDN). Добавляем в проект собственный скрипт (обсуждаем, почему его стоит писать в конце файла и как это связано с тем, как браузер скачивает ресурсы). Учимся уже знакомыми селекторами выбирать элементы и менять их. Рассматриваем свойство display: none. Скрываем боковую менюшку. Делаем то же самое по таймауту. Эксперименты проводим в консоли разработчика, потом заносим в скрипт.
Говорим про браузерные события. Создаем кнопку, которая onclick скрывает/показывает менюшку. Меняем кнопку на ссылку и обсуждаем event.preventDefault и всплывание событий. Наверняка у кого-нибудь в процессе будут опечатки, и всё пойдет не так, так что говорим про console.log и отладку.
Тренируемся работать с javascript. Добавляем на страничку таймер, которые измеряют, сколько времени пользователь уже смотрит презентацию. Добавляем ещё один таймер, который меряет, сколько времени показывается текущий слайд (пользуемся пользовательским событием slidechanged).
Занятие 5
У нас уже большой проект, который легко испортить. Чтобы не случалось непоправимых вещей, мы сделаем контроль версий. Повторяем про контроль версий и почему это важно. Обсуждаем как устроен git технически: Что в гите хранятся все версии всех файлов, а гит только достаёт наружу нужные версии файлов. Что версии имеют родителей. Что есть ветки, и они являются просто (сдвигающимися) ярлыками для версий. Что есть удаленные репозитории (равноправные), с которыми можно обмениваться изменениями, в частности такой репозиторий можно завести на гитхабе. Что есть три области: рабочая папка, индекс, коммиты. После этого введения мы начинаем рисовать стрелочки между этими областями и вводить команды.
Здесь нам придется работать с командной строкой - мы изучаем минимум: cd/pwd/cp/mv/rm (очень желательно на этом месте иметь unix-утилиты даже если мы работаем в windows; и потому что они намного лучше проработаны, и чтобы не учить второй набор команд, когда мы будем работать с linux-сервером по ssh).
Мы создаем репозиторий. Дорисовывая стрелочки на схему git-областей выполняем команды добавления файлов в индекс, делаем первый коммит. Вносим изменения, смотрим diff и статус. Откатываем изменения, вносим другие и делаем коммит. Снова смотрим статус и логи. Создаем аккаунт и репозиторий на гитхабе, соединяем его с репозиторием на компьютере. Если остается время, добавляем проекту README.md и говорим про разметку markdown.
Занятие 6
Переходим к бэкенду. “У нас есть сайт с тремя презентациями и мы уже видим, как кучу кода приходится дублировать. При добавлении ещё одной презентации нам придется менять всё. Давайте это менять, генерируя странички на лету”. Обсуждаем, сколько страниц было бы у вконтакта, если бы он каждую страницу хранил в отдельном файле и сколько он файлов обновлял бы при отправке каждого комментария.
Теперь заведем текстовые файлы, в которых будет лежать код самой презентации, а обертку: подключаемые стили и скрипты, менюшку итд запишем отдельно. Когда мы это сделали, давайте научимся собирать страницы из кусочков при помощи питона.
После того как это получилось, мы делаем небольшой сервер на BottlePy (как наиболее минималистичном фреймворке), который по номеру страницы собирает html-ку и отдает её клиенту. Делаем сначала четыре endpoint-а: главная страница + по одному на каждую презентацию. Потом обобщаем три эндпоинта в единую точку “просмотреть презентацию номер ID”. Попутно смотрим, чем отличается вывод с помощью print (в консоль) и с помощью return (который идёт в ответ пользователю).
Делаем общий шаблон сайта и шаблон страниц с презентациями.
Занятия 7-8
Сделаем счетчик числа просмотров и числа лайков для каждой презентации (их будем хранить прямо в памяти приложения, при перезапуске он будет сбрасываться). Поговорим про семантику GET и POST запросов (и почему, если на сайт заходят краулеры, не стоит делать модифицирующие сайт запросы методом GET). Говорим про формы. Делаем формочку для отправки комментариев к презентации: имя, текст, кнопка отправки.
Сделаем так, чтобы нельзя было поставить два лайка с одного IP. Когда из запроса мы научились извлекать IP, помотрим на “метаданные” и заголовки HTTP-запроса. Сравниваем эти метаданные в браузере и на стороне сервера.
Здесь может потребоваться посерьезнее обсудить структуры данных питона: массивы и словари. Тем, кто знает, можно дать задание в плюс к сообщению хранить время записи итд. Или сделать лайки не только к постам, но и к сообщениям.
Обсуждем, что такое куки, для чего они хороши, для чего плохи. Обсуждаем как работают рекламные сети. Если занятие бодро идёт, можно поговорить о том, что сайты/pdf-ки могут сообщать злоумышленнику, например, об открытии документа за счет того, что грузят картинку/шрифты с чужого сайта.
Добавляем логин на сайт (фактически просто выбор имени); пока что через cookie, без пароля. Когда в куках установлен пользователь, вместо поля ввода имени показываем строку приветствия и кнопку “выйти”.
Занятие 9
Говорим про реляционные базы данных. Обсуждаем, как уложить презентации, пользователей и комменты/лайки в таблицу. Заведем базу данных (sqlite более чем достаточно) и при помощи какой-нибудь ORM (например, peewee) создадим пару таблиц и их моделей. Делаем так, что комментарии сохраняются и загружаются из базы.
Тут, наверное, потребуется поговорить немного про классы. Инкапсуляция + чуууточку наследования (чтобы объяснить синтаксис наследования классов таблиц от базовой модели); всерьез рассказывать про ООП тут не надо. В данном случае класс - это просто “словарь на стероидах”: тоже хранит данные, но обращаться к нему можно через точку, а часть вещей, которые не хранятся, он сам вычисляет.
Занятие 10
Знакомимся с ssh и учимся работать с удаленным сервером. Каждый школьник заходит в аккаунт своего пользователя на VPS и клонирует туда свой репозиторий.
Вероятно, уместно будет обсудить тему прав доступа, раз уж все на единой машине. Разбираемся с виртуальным окружением. Заводим файл requirements.txt и говорим про версионирование библиотек.
Они запускают свои сервера на разных портах. Говорим про мультиплексор screen/tmux. Дальше мы обсуждаем, что такое IP-адрес, порт, hostname и говорим про DNS. Потом говорим про nginx и маршрутизацию запросов на несколько веб-сервисов внутри машины, в зависимости от имени сайта. После разговора про порты можно упомянуть про firewall.
Занятие 11 (лекционное)
Лекция о сетевой безопасности и принцип “не пиши свою криптографию” (кодовое название “как страшно жить”).
Пароли: как их взламывают и почему пароли важно хранить в солёном виде. Хэш-функции как подпись и чем может грозить алгоритм, допускающий коллизии.
Что такое симметричное и асимметричное шифрование, как асимметричное шифрование устроено (в общих чертах). Применение асимметричного шифрования для секретной передачи данных или для подписи открытого сообщения.
Почему небезопасен HTTP, и как устроен HTTPS. Что такое MITM и для чего нужны сертификаты безопасности. Что такое XSS (а также атаки повторения) в общих чертах и как от них защищаются. Атаки уровня сети - DNS spoofing.
Занятие 12
Делаем аутентификацию; вероятнее всего при помощи сторонней библиотеки. Привязываем комментарии к пользователям. Ставим пометку о тех уязвимостях, которые у нас остались (отсутствие https как минимум). Говорим про OAuth. Обсуждаем концепцию 2FA и разные её реализации (sms/TOTP).
Отличие аутентификации от авторизации. Заводим роль администратора/модератора, который может удалять чужие презентации.
Занятие 13
Делаем API для того, чтобы ставить/просматривать лайки. Теперь мы будем ставить лайки при помощи AJAX-запроса. Смотрим на JSON. Вспоминаем jquery и вешаем onclick/onhover на значок “лайк”.
Занятие 14
Наполним сайт чужими презентациями. Для этого нам придется написать небольшой краулер со slideshare, slides.com (работа со slideshare - это повод заодно поговорить про прокси) или их аналогов. Заглядываем в консоль браузера и мониторим запросы. Выделяем те запросы, которые отвечают за скачивание презентации, пытаемся понять, как они сделаны. Пишем робота, который при помощи requests моделирует эти запросы.
Заходим на другой сайт, который сделан более статическим. Делаем запрос, получаем содержимое html-страницы и при помощи BeautifulSoup парсим его.
Заходим на третий сайт и моделируем работу пользователя с ним при помощи selenium.
Здесь надо аккуратно подобрать сайты, чтобы задача была подъемной. Каждый школьник должен выбрать что-то одно, чтобы успеть. Возможно, это занятие уходит в опциональную часть.
Занятие 15-…
Теперь каждый может в свою сторону развивать проект. В идеале несколько человек объединяются и работают по 2-3 человека и учатся работать в команде. Тут можно обойтись уже без общих лекций, а консультировать каждую группу в частном порядке. Направления, которые я предложу - такие:
- конструктор презентаций и шаблоны типовых слайдов
- добавить заливку картинок на сайт
- расшаривание слайдов между презентациями
- разграничение прав доступа к презентациям
- предпросмотр страниц сайта в соцсетях за счет opengraph-разметки
- вход с помощью OAuth; заодно аватары пользователей можно получать с gravatar
- отправка оповещений по почте
- интеграция c github, чтобы презентации сохранялись прямо туда и оттуда же подтягивались
- сделать telegram-бота, который позволяет добавлять типовые слайды при помощи сообщений в телеграм - чтобы можно было редактировать презентации с телефона
- переписать дизайн на bootstrap
Технические требования
Мне понадобятся:
- интернет
- возможность сохранять работу между занятиями (т.е. закрепленные за школьниками компьютеры или же школьники могут работать на собственных ноутах)
- python 3 (лучше 3.6+) с библиотеками requests, bottlePy, peewee, beautifulsoup.
- вменяемый редактор (предпочтительно sublime text)
- вменяемый браузер (желательно chrome, но firefox тоже ок)
- git; если на компьютерах windows, то КРАЙНЕ желательно при установке добавить утилиты bash в командную строку “Run Git and included Unix tools from the Windows Command Prompt” несмотря на красненький warning
- SmarTTY, WinSCP (если на компьютерах windows)
- curl
- Хорошо было бы завести простенький VPS, например, на Digital Ocean ($6 / месяц), либо на школьном сервере, чтобы школьники могли захостить свой сайт. У меня есть виртуалка на DO, но я не уверен, хватит ли её.