Настройка контроля доступа (Access Control) Payload CMS

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Настройка контроля доступа (Access Control) Payload CMS
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Контроль доступа в Payload CMS

Payload реализует контроль доступа через функции, возвращающие true, false или объект-условие (MongoDB query / SQL WHERE). Нет YAML-конфигов или GUI — только TypeScript-функции, которые получают контекст запроса и возвращают решение.

Структура Access Control

// Функция доступа получает: req (с req.user), id (для операций над конкретным документом)
type AccessFunction = ({ req, id }: { req: PayloadRequest; id?: string | number }) =>
  boolean | Where | Promise<boolean | Where>

Where — это объект-условие, который Payload передаёт в запрос к БД. Это значит, что пользователь получает только документы, удовлетворяющие условию — не проверку на каждый документ по отдельности.

Роли пользователей

// collections/Users.ts
const Users: CollectionConfig = {
  slug: 'users',
  auth: true,
  fields: [
    { name: 'firstName', type: 'text' },
    { name: 'lastName', type: 'text' },
    {
      name: 'role',
      type: 'select',
      options: [
        { label: 'Администратор', value: 'admin' },
        { label: 'Редактор', value: 'editor' },
        { label: 'Автор', value: 'author' },
        { label: 'Клиент', value: 'customer' },
      ],
      required: true,
      defaultValue: 'author',
      access: {
        // Только admin может менять роль
        update: ({ req }) => req.user?.role === 'admin',
      },
    },
  ],
}

Контроль доступа к коллекции

// collections/Posts.ts
const Posts: CollectionConfig = {
  slug: 'posts',
  access: {
    // Публичное чтение только опубликованных
    read: ({ req }) => {
      if (req.user?.role === 'admin' || req.user?.role === 'editor') {
        return true  // Видят всё
      }
      return {
        status: { equals: 'published' }  // Остальные только published
      }
    },

    // Создавать могут editor и author
    create: ({ req }) =>
      ['admin', 'editor', 'author'].includes(req.user?.role || ''),

    // Обновлять: admin/editor — всё, author — только своё
    update: ({ req }) => {
      if (!req.user) return false
      if (['admin', 'editor'].includes(req.user.role)) return true
      if (req.user.role === 'author') {
        return { author: { equals: req.user.id } }
      }
      return false
    },

    // Удалять только admin
    delete: ({ req }) => req.user?.role === 'admin',
  },
}

Контроль доступа на уровне поля

fields: [
  {
    name: 'internalNotes',
    type: 'textarea',
    access: {
      // Поле видно только admin и editor
      read: ({ req }) => ['admin', 'editor'].includes(req.user?.role || ''),
      // Обновлять может только admin
      update: ({ req }) => req.user?.role === 'admin',
    },
  },
  {
    name: 'publishedAt',
    type: 'date',
    access: {
      // Дату публикации устанавливает только editor или admin
      update: ({ req }) => ['admin', 'editor'].includes(req.user?.role || ''),
    },
  },
]

Динамический доступ через организации

Для мультитенантных схем — доступ через связанную организацию:

// collections/Documents.ts
{
  slug: 'documents',
  access: {
    read: ({ req }) => {
      if (!req.user) return false
      if (req.user.role === 'admin') return true

      // Пользователь видит только документы своей организации
      return {
        organization: { equals: req.user.organization }
      }
    },
    update: ({ req }) => {
      if (!req.user) return false
      if (req.user.role === 'admin') return true
      return {
        and: [
          { organization: { equals: req.user.organization } },
          { lockedBy: { not_equals: req.user.id } },  // не заблокирован другим
        ]
      }
    },
  },
}

Защита API эндпоинтов

// Кастомный эндпоинт с проверкой доступа
{
  path: '/export',
  method: 'get',
  handler: async (req: PayloadRequest, res: Response) => {
    // Проверка аутентификации
    if (!req.user) {
      return res.status(401).json({ error: 'Unauthorized' })
    }

    // Проверка роли
    if (!['admin', 'editor'].includes(req.user.role)) {
      return res.status(403).json({ error: 'Insufficient permissions' })
    }

    // Аудит лог
    await req.payload.create({
      collection: 'audit-logs',
      data: {
        action: 'export',
        user: req.user.id,
        timestamp: new Date().toISOString(),
      },
    })

    const data = await req.payload.find({ collection: 'documents', limit: 10000 })
    return res.json(data)
  },
}

Публичное API с ограничениями

// Для публичных запросов (без авторизации)
read: ({ req }) => {
  if (!req.user) {
    // Только активные, только часть полей
    return {
      and: [
        { status: { equals: 'active' } },
        { visibleToPublic: { equals: true } },
      ]
    }
  }
  return true
}

Utility-хелперы для переиспользования

// utils/access.ts
export const isAdmin = ({ req }: AccessArgs) => req.user?.role === 'admin'
export const isEditorOrAbove = ({ req }: AccessArgs) =>
  ['admin', 'editor'].includes(req.user?.role || '')
export const isAuthenticated = ({ req }: AccessArgs) => Boolean(req.user)
export const isOwner = ({ req, id }: AccessArgs) => {
  if (!req.user) return false
  if (req.user.role === 'admin') return true
  return { createdBy: { equals: req.user.id } }
}

// Использование:
access: {
  read: () => true,
  create: isAuthenticated,
  update: isOwner,
  delete: isAdmin,
}

Сроки

Настройка системы ролей и контроля доступа для проекта с 3–5 ролями и 5–10 коллекциями — 2–3 дня.