0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>В веб-приложениях часто есть логика, которая должна выполняться перед обработкой любого запроса. К такой логике относятся: проверка доступа, логирование запроса, ограничение количества запросов. Перед веб-разработчиками часто встает проблема в организации такой логики, чтобы разрабатывать без сложностей и поддерживать приложение.</p>
1
<p>В веб-приложениях часто есть логика, которая должна выполняться перед обработкой любого запроса. К такой логике относятся: проверка доступа, логирование запроса, ограничение количества запросов. Перед веб-разработчиками часто встает проблема в организации такой логики, чтобы разрабатывать без сложностей и поддерживать приложение.</p>
2
<p>Чтобы решить эту проблему, в веб-приложениях используются посредники, которые выполняются перед обработчиками HTTP-запросов. В этом уроке мы научимся использовать посредников в микрофреймворке Fiber и разберем конкретные примеры реализации.</p>
2
<p>Чтобы решить эту проблему, в веб-приложениях используются посредники, которые выполняются перед обработчиками HTTP-запросов. В этом уроке мы научимся использовать посредников в микрофреймворке Fiber и разберем конкретные примеры реализации.</p>
3
<h2>Middlewares</h2>
3
<h2>Middlewares</h2>
4
<p>Посредники или middlewares в Fiber являются функциями func(c *fiber.Ctx) error, которые мы устанавливаем перед обработчиками. Посредник может изменять запрос, добавлять заголовки, выполнять логирование. Посредник также может прервать цепочку обработки запроса, если возникла ошибка.</p>
4
<p>Посредники или middlewares в Fiber являются функциями func(c *fiber.Ctx) error, которые мы устанавливаем перед обработчиками. Посредник может изменять запрос, добавлять заголовки, выполнять логирование. Посредник также может прервать цепочку обработки запроса, если возникла ошибка.</p>
5
<p>Пример посредника, который проверяет возможность доступа пользователя к веб-приложению, может выглядеть следующим образом:</p>
5
<p>Пример посредника, который проверяет возможность доступа пользователя к веб-приложению, может выглядеть следующим образом:</p>
6
<p>В примере выше мы создали посредник accessMiddleware, который проверяет наличие корректного токена доступа в параметрах запроса. Если токен не прошел проверку, то посредник прерывает цепочку обработки запроса и возвращает клиенту статус<em>401 Unauthorized</em>. Если токен валиден, то посредник вызывает метод c.Next(), который продолжает обработку запроса.</p>
6
<p>В примере выше мы создали посредник accessMiddleware, который проверяет наличие корректного токена доступа в параметрах запроса. Если токен не прошел проверку, то посредник прерывает цепочку обработки запроса и возвращает клиенту статус<em>401 Unauthorized</em>. Если токен валиден, то посредник вызывает метод c.Next(), который продолжает обработку запроса.</p>
7
<p>Такой подход работает, когда мы хотим использовать посредника на всех обработчиков в приложении. Но бывают ситуации, когда нам нужно использовать посредник только на некоторых обработчиках.</p>
7
<p>Такой подход работает, когда мы хотим использовать посредника на всех обработчиков в приложении. Но бывают ситуации, когда нам нужно использовать посредник только на некоторых обработчиках.</p>
8
<h2>Группировка запросов в маршрутизации</h2>
8
<h2>Группировка запросов в маршрутизации</h2>
9
<p>Чтобы назначить посредника только на некоторые обработчики в Fiber, их нужно сначала сгруппировать с помощью функции r.Group(). После этого мы можем устанавливать посредников для всей группы с помощью r.Use():</p>
9
<p>Чтобы назначить посредника только на некоторые обработчики в Fiber, их нужно сначала сгруппировать с помощью функции r.Group(). После этого мы можем устанавливать посредников для всей группы с помощью r.Use():</p>
10
<p>В примере выше мы создали две группы запросов:<em>authGroup</em>и<em>publicGroup</em>. В группу<em>authGroup</em>мы добавили посредник<em>accessMiddleware</em>, который проверяет наличие корректного токена доступа в параметрах запроса. В группу<em>publicGroup</em>мы не добавили посредников, поэтому при запросах к группе сразу выполняются обработчики:</p>
10
<p>В примере выше мы создали две группы запросов:<em>authGroup</em>и<em>publicGroup</em>. В группу<em>authGroup</em>мы добавили посредник<em>accessMiddleware</em>, который проверяет наличие корректного токена доступа в параметрах запроса. В группу<em>publicGroup</em>мы не добавили посредников, поэтому при запросах к группе сразу выполняются обработчики:</p>
11
<p>Мы разобрались, как создавать своих посредников в Fiber. Но также существует набор готовых посредников, которые мы можем подключать в своих проектах. Каждый посредник представлен отдельным пакетом, который можно добавлять в проект при необходимости. Рассмотрим самые популярные из них.</p>
11
<p>Мы разобрались, как создавать своих посредников в Fiber. Но также существует набор готовых посредников, которые мы можем подключать в своих проектах. Каждый посредник представлен отдельным пакетом, который можно добавлять в проект при необходимости. Рассмотрим самые популярные из них.</p>
12
<h2>Логирование запросов</h2>
12
<h2>Логирование запросов</h2>
13
<p>Логирование необходимо для отладки работающих веб-приложений. Помимо явного логирования в местах ошибок, мы можем добавить логирование всех запросов. Так мы будем понимать, какие запросы приходят в приложение, по какому пути и с какими параметрами.</p>
13
<p>Логирование необходимо для отладки работающих веб-приложений. Помимо явного логирования в местах ошибок, мы можем добавить логирование всех запросов. Так мы будем понимать, какие запросы приходят в приложение, по какому пути и с какими параметрами.</p>
14
<p>Чтобы добавить логирование всех запросов в Fiber-приложение, нужно подключить к проекту пакет<em>github.com/gofiber/fiber/v2/middleware/logger</em>и инициализировать его перед всеми обработчиками:</p>
14
<p>Чтобы добавить логирование всех запросов в Fiber-приложение, нужно подключить к проекту пакет<em>github.com/gofiber/fiber/v2/middleware/logger</em>и инициализировать его перед всеми обработчиками:</p>
15
<p>Запускаем веб-приложение и переходим в браузере на страницу<em><a>http://localhost</a></em>. Видим, что в ответ пришло сообщение "OK". При этом в консоли веб-приложения появилось сообщение о залогированном запросе:</p>
15
<p>Запускаем веб-приложение и переходим в браузере на страницу<em><a>http://localhost</a></em>. Видим, что в ответ пришло сообщение "OK". При этом в консоли веб-приложения появилось сообщение о залогированном запросе:</p>
16
<p>Если несколько раз перезагружать страницу<em><a>http://localhost</a></em>, мы увидим несколько записей лога.</p>
16
<p>Если несколько раз перезагружать страницу<em><a>http://localhost</a></em>, мы увидим несколько записей лога.</p>
17
<p>Так мы добавили логирование всех запросов в наше веб-приложение. По умолчанию логирование происходит в консоль, но можно настроить логирование в файл или в другие системы логирования.</p>
17
<p>Так мы добавили логирование всех запросов в наше веб-приложение. По умолчанию логирование происходит в консоль, но можно настроить логирование в файл или в другие системы логирования.</p>
18
<p>Также при инициализации посредника для логирования мы можем указать формат логов, который подходит для нашего проекта. Для этого нужно передать в функцию инициализации посредника параметр logger.Config:</p>
18
<p>Также при инициализации посредника для логирования мы можем указать формат логов, который подходит для нашего проекта. Для этого нужно передать в функцию инициализации посредника параметр logger.Config:</p>
19
<p>Запускаем веб-приложение и переходим в браузере на страницу<em><a>http://localhost</a></em>. Видим, что в ответ пришло сообщение "OK". При этом в консоли веб-приложения изменился формат логов:</p>
19
<p>Запускаем веб-приложение и переходим в браузере на страницу<em><a>http://localhost</a></em>. Видим, что в ответ пришло сообщение "OK". При этом в консоли веб-приложения изменился формат логов:</p>
20
<p>Также хорошей практикой считается логировать идентификатор, который поможет нам связать все логи в рамках одного запроса. Для этого нам нужно подключить к проекту пакет<em>github.com/gofiber/fiber/v2/middleware/requestid</em>. И инициализировать его перед посредником для логирования:</p>
20
<p>Также хорошей практикой считается логировать идентификатор, который поможет нам связать все логи в рамках одного запроса. Для этого нам нужно подключить к проекту пакет<em>github.com/gofiber/fiber/v2/middleware/requestid</em>. И инициализировать его перед посредником для логирования:</p>
21
<p>Запускаем веб-приложение и открываем в браузере страницу<em><a>http://localhost</a></em>. После этого проверяем консоль веб-приложения:</p>
21
<p>Запускаем веб-приложение и открываем в браузере страницу<em><a>http://localhost</a></em>. После этого проверяем консоль веб-приложения:</p>
22
<p>Мы видим, что теперь в каждом логе есть идентификатор запроса. Если что-то пойдет не так, по идентификатору мы сможем понять, в рамках какого запроса происходили ошибки. Это поможет при отладке или исправлении ошибок в работающем веб-приложении.</p>
22
<p>Мы видим, что теперь в каждом логе есть идентификатор запроса. Если что-то пойдет не так, по идентификатору мы сможем понять, в рамках какого запроса происходили ошибки. Это поможет при отладке или исправлении ошибок в работающем веб-приложении.</p>
23
<p>Логирование запросов помогает нам разобраться в возникающих ошибках, но есть посредники, которые позволяют предотвратить новые ошибки. Один из примеров таких посредников - ограничение количества запросов в единицу времени.</p>
23
<p>Логирование запросов помогает нам разобраться в возникающих ошибках, но есть посредники, которые позволяют предотвратить новые ошибки. Один из примеров таких посредников - ограничение количества запросов в единицу времени.</p>
24
<h2>Ограничение количества запросов</h2>
24
<h2>Ограничение количества запросов</h2>
25
<p>Представим, что у нас есть небольшое веб-приложение, у которого сто клиентов, и все работает бесперебойно. Конкурент завидует нашему успеху и решает написать скрипт, который будет отправлять миллионы запросов в наше приложение. Цель конкурента - вывести наши сервера из работы, чтобы клиенты не могли пользоваться приложением, и бизнес терял прибыль.</p>
25
<p>Представим, что у нас есть небольшое веб-приложение, у которого сто клиентов, и все работает бесперебойно. Конкурент завидует нашему успеху и решает написать скрипт, который будет отправлять миллионы запросов в наше приложение. Цель конкурента - вывести наши сервера из работы, чтобы клиенты не могли пользоваться приложением, и бизнес терял прибыль.</p>
26
<p>Чтобы защититься со стороны веб-приложения от таких атак, следует настроить ограничение количества запросов - throttling. Для этого мы будем использовать пакет<em>github.com/gofiber/fiber/v2/middleware/limiter</em>. Когда пакет подключен, мы можем настроить нового посредника, чтобы ограничить количество запросов с одного IP-адреса:</p>
26
<p>Чтобы защититься со стороны веб-приложения от таких атак, следует настроить ограничение количества запросов - throttling. Для этого мы будем использовать пакет<em>github.com/gofiber/fiber/v2/middleware/limiter</em>. Когда пакет подключен, мы можем настроить нового посредника, чтобы ограничить количество запросов с одного IP-адреса:</p>
27
<p>Запускаем веб-приложение и открываем в браузере страницу<em><a>http://localhost</a></em>четыре раза. На первые три запроса мы получаем ответ "OK", но на четвертый получаем ответ "Too Many Requests".</p>
27
<p>Запускаем веб-приложение и открываем в браузере страницу<em><a>http://localhost</a></em>четыре раза. На первые три запроса мы получаем ответ "OK", но на четвертый получаем ответ "Too Many Requests".</p>
28
<p>С помощью структуры limiter.Config мы установили максимальное количество запросов в единицу времени. В нашем случае это три запроса в десять секунд. Если мы превысим это количество, то наш запрос будет отклонен с кодом<em>429 (Too Many Requests)</em>, что мы и увидели на четвертый запрос. По истечении десяти секунд с момента первого запроса мы снова сможем открывать страницу и получать успешный ответ.</p>
28
<p>С помощью структуры limiter.Config мы установили максимальное количество запросов в единицу времени. В нашем случае это три запроса в десять секунд. Если мы превысим это количество, то наш запрос будет отклонен с кодом<em>429 (Too Many Requests)</em>, что мы и увидели на четвертый запрос. По истечении десяти секунд с момента первого запроса мы снова сможем открывать страницу и получать успешный ответ.</p>
29
<p>В данном примере мы использовали IP-адрес клиента, чтобы определить источник запроса. Но можно использовать любой другой идентификатор, например, идентификатор пользователя или сессии.</p>
29
<p>В данном примере мы использовали IP-адрес клиента, чтобы определить источник запроса. Но можно использовать любой другой идентификатор, например, идентификатор пользователя или сессии.</p>
30
<h2>Выводы</h2>
30
<h2>Выводы</h2>
31
<ul><li>Посредники позволяют выполнять действия до или после обработки запроса</li>
31
<ul><li>Посредники позволяют выполнять действия до или после обработки запроса</li>
32
<li>Fiber позволяет группировать обработчиков, чтобы один раз описывать всех посредников для группы обработчиков</li>
32
<li>Fiber позволяет группировать обработчиков, чтобы один раз описывать всех посредников для группы обработчиков</li>
33
<li>Посредники могут быть использованы для логирования запросов, проверки доступа, ограничения количества запросов</li>
33
<li>Посредники могут быть использованы для логирования запросов, проверки доступа, ограничения количества запросов</li>
34
</ul>
34
</ul>