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

Web3: вход и проверка права читателя

Оглавление курса «Web3: вход, смарт-аккаунты и индексатор» · Урок 9 из 30.

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

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

Субъект, действие и ресурс

Для решения нужны три элемента: проверенный субъект сессии, действие и ресурс. Например, адрес A хочет сохранить собственный прогресс курса17. Сервер извлекает адрес из сессии, номер курса — из проверенного маршрута, а действие определяет endpoint. Клиент не передаёт role = reader как окончательное разрешение.

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

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

Простая серверная политика

Начнём с полного чистого решения для подготовленного объекта сессии и серверного назначения. Функция не знает HTTP или базу; эти адаптеры получают проверенные данные отдельно.

export function authorizeProgress({ session, entitlement, courseId, now }) {
  if (!session || session.revoked || session.expiresAt <= now) {
    return { allowed: false, reason: 'authentication_required' };
  }
  if (!entitlement || entitlement.address !== session.address
      || entitlement.courseId !== courseId || !entitlement.active) {
    return { allowed: false, reason: 'course_not_assigned' };
  }
  return { allowed: true, address: session.address, courseId };
}

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

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

Право и данные другого пользователя

Endpoint прогресса не принимает адрес владельца как свободный переключатель. Для сохранения собственного прогресса он использует субъект сессии. Администраторский маршрут работы с другим аккаунтом выделяется отдельно и проверяет отдельную роль. Нельзя сделать его случайным ответвлением «если клиент прислал другой address».

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

Ответы с отказом не раскрывают чужие персональные сведения. Если адрес B не имеет доступа, интерфейс сообщает отсутствие права или необходимость входа по политике. Он не выдаёт историю оплаты A или внутренние заметки редакции. Диагностические причины остаются в ограниченном журнале сервиса.

Токеновое расширение

Если право позже определяется токеном, нужен отдельный контракт и интерфейс. CourseCatalog.courses(17) возвращает выпуск, а не баланс читателя. Можно добавить адаптер чтения выбранного токена с сетью, адресом и блоком, но его нельзя выдумать внутри базового ABI. Правило права описывает, какие единицы или идентификаторы считаются достаточными.

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

Токеновая проверка не скрывает файл, который уже публично доступен по URL или опубликован в IPFS. Она ограничивает действия сервера или выдачу закрытого содержимого в выбранной архитектуре. Если сам документ открыт всем, интерфейсная кнопка не превращает его в секрет. Это важное ограничение для учебного сайта с открытыми статьями.

Недоступный источник

Если RPC не отвечает, сервер не должен бесконечно ждать на каждом запросе пользователя. Возможны ограниченное чтение, кеш с явной политикой или временный отказ персонального действия. Выбор определяется продуктом и уровнем риска. Нельзя рекомендовать принимать любое старое положительное право без срока и объяснения.

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

Ожидаемые случаи

Действующая сессия и назначение собственного курса разрешают сохранение. Правильная подпись без назначения не разрешает его автоматически. Клиентский address не меняет субъекта. Отозванное право прекращает разрешение по выбранной серверной политике. Неизвестный ответ источника не принимается как положительный. Эти критерии здесь не исполнялись.

Для упражнения разделите вход, роль сайта, publisher реестра и токеновое право. Укажите источник каждого значения и действие, которое оно разрешает. Ожидаемый итог — кабинет читателя имеет точную область полномочий, а подпись не становится универсальным пропуском. Принципы авторизации описаны в OWASP Authorization.

Авторизация и состояние операции

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

В интерфейсе это разные сообщения: «Войдите», «Курс не назначен» и «Источник права временно недоступен». Последнее не превращается в отрицательный постоянный факт, а сохраняет неопределённость наблюдения. Серверный журнал связывает решение с использованным источником и временем, чтобы будущий разбор отличал отзыв права от сбоя инфраструктуры.

Оглавление серии