Перейти к содержанию

Права на чтение и изменение

Сессия уже хранит роль на сервере и проверяет защитный токен формы. Теперь введём политику доступа: читатель смотрит оборудование, редактор создаёт и меняет карточки и проводит движения. Демонстрационный выбор роли остаётся локальным и не проверяет личность. Новый результат урока — правильное место решения о праве, а не полноценный корпоративный вход. Эти границы должны быть понятны до обсуждения красивой кнопки «Войти».

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

Чтение и изменение

В текущем договоре список доступен для локального чтения независимо от выбранной роли. Создание и редактирование требуют editor. Это осознанная учебная политика: в настоящей компании даже список оборудования может быть закрыт. Нельзя считать её универсальной нормой только потому, что пример называется корпоративным. Для нового предметного приложения сначала определите, какие сведения можно раскрывать, а затем переносите правило на все пути чтения, включая фильтры и отдельные карточки.

GET-обработчики новой карточки и редактирования проверяют роль до выдачи формы. POST-обработчики используют guard, где после CSRF находится проверка editor. Движение использует тот же guard, поэтому не становится случайно обходным маршрутом. Удобно собрать одинаковое решение в одну функцию, но важно сохранить ясный порядок: сначала корректность обращения и сессионного основания, затем право, затем предметная проверка и только после неё SQL.

if s.Role!="editor"{http.Error(w,"Недостаточно прав",403);return false}

Этот фрагмент находится внутри guard состояния lesson-13. Роль берётся из Session, которую сервер нашёл по cookie. Значение role из тела операции оборудования не участвует в решении. Даже если клиент отправит role=editor, оно не сменит текущую сессию. Учебный отдельный маршрут выбора роли существует только для демонстрации и всегда обозначен в интерфейсе как отсутствие проверки личности.

Почему CSRF недостаточно

Правильный защитный токен означает, что POST связан с текущей сессией. У читателя есть свой действительный токен, но это не даёт ему право изменять оборудование. Поэтому проверка роли выполняется после проверки токена. Если остановиться на CSRF, viewer сможет использовать собственную форму или ручной клиент для записи. Сессионная принадлежность и полномочия субъекта — разные вопросы; одинаковое присутствие cookie не объединяет их в один механизм.

Также не используем HX-Request как признак доверия. Этот заголовок управляет выбором panel, и любой клиент способен его подставить. HTML-представление не определяет право. Маршруты должны одинаково отказать обычной форме, htmx и прямому POST. Такая независимость особенно полезна при развитии приложения: появление мобильного клиента не требует заново переосмысливать корпоративное правило и не создаёт второй набор полномочий по умолчанию.

В шаблоне формы находятся внутри условия роли. Viewer видит объяснение, а editor — элементы создания и изменения. Ссылки в таблице можно сделать ещё точнее, убрав недоступное редактирование из каждой строки для читателя. В текущем полном состоянии серверная граница уже действует; изменение разметки нужно оценивать как удобство интерфейса, а не как единственную защиту. Нельзя утверждать, что право отсутствует, только потому, что кнопку не видно.

Договор отказа

При отсутствии права возвращаем 403 до предметной операции. Это отличается от 409 при устаревшей версии и 422 при неправильном SKU. Человек не может исправить запрет права изменением названия оборудования. Если смешать все причины в сообщение «не удалось сохранить», дальнейшее действие останется непонятным. Для сотрудника и разработчика важно знать, требуется ли обновить карточку, исправить поле или получить разрешение.

Запрет не должен приводить к частичному движению. В нашем коде guard выполняется до BeginTx, поэтому ни остаток, ни журнал не меняются. Если право проверять после UPDATE и перед INSERT, отказ может оставить неполный результат при ошибке границ транзакции. Предметное решение о допустимости должно предшествовать началу работы, насколько позволяют требования; дополнительные проверки внутри SQL могут охранять условия состояния, но не исправляют неверную последовательность автоматически.

Рассмотрим viewer с правильной сессией и токеном, который отправляет создание MOUSE-001. Ожидается 403 и отсутствие новой строки. Затем тот же человек выбирает editor через демонстрационный маршрут, получает новую сессию и отправляет свежую форму. При правильных предметных данных операция проходит. Старую форму нельзя считать эквивалентной свежей: смена сессии также изменила CSRF, поэтому её отказ имеет другое основание.

Расширение политики

Две роли подходят небольшому стенду, но настоящее приложение может различать редактора названия, кладовщика движения и аудитора журнала. Тогда проверка одной строки editor становится слишком грубой. Полезнее именованные разрешения вида item.create, item.update, stock.move, а роли только объединяют их. Такой переход должен сохранять карту операций и решений, чтобы новый маршрут не получил доступ случайно из-за сходства с уже существующим действием.

Ещё одна граница — принадлежность объекта. Пользователь может иметь право редактировать оборудование своего подразделения, но не чужого. Тогда наличие общего разрешения недостаточно: сервер должен получить предметный объект и проверить область доступа. ID в адресе не является секретом, а скрытая ссылка не ограничивает знание других идентификаторов. Наш курс пока не вводит подразделения, поэтому не обещает защиты на уровне владения каждой карточкой.

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

Примеры отказов и успешных переходов описывают ожидаемое поведение полного состояния lesson-13; при подготовке они не запускались. Следующий урок завершит серверную часть таймаутами и штатной остановкой. Права уже будут отделены от представления, а внимание перейдёт к жизненному циклу процесса: как перестать принимать новые соединения, завершить текущую работу и не потерять понимание состояния локальной базы.

Исходники урока

Оглавление серии · Скачать исходники. Полное самостоятельное состояние находится в lesson-13. Учебные приложения, зависимости, база и проверки при подготовке не запускались; описанный результат ожидается по исходникам. Материалы пока находятся в локальной редакционной версии.

Первичные источники: документация 1.