Реализация управления согласиями на обработку данных на сайте

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация управления согласиями на обработку данных на сайте
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Реализация управления согласиями на обработку данных на сайте

Управление согласиями (Consent Management) — система, которая фиксирует, хранит и обрабатывает юридически значимые согласия пользователей на обработку персональных данных в соответствии с GDPR, 152-ФЗ и другими регуляторными требованиями.

Типы согласий

Тип Примеры Обязательность
Обработка ПДн Регистрация, форма заказа Обязательно
Маркетинговые коммуникации Email-рассылка, SMS По запросу
Профилирование Рекомендации, аналитика По запросу
Передача третьим лицам Партнёры, рекламные сети По запросу
Cookies (неосновные) Аналитика, ремаркетинг По запросу

Структура базы данных

-- Типы согласий
CREATE TABLE consent_types (
    id           SERIAL PRIMARY KEY,
    code         VARCHAR(50) UNIQUE NOT NULL,  -- 'marketing_email', 'data_processing'
    title        VARCHAR(255) NOT NULL,
    description  TEXT NOT NULL,
    version      VARCHAR(20) NOT NULL,         -- '1.2' — при изменении политики
    is_required  BOOLEAN DEFAULT FALSE,
    created_at   TIMESTAMPTZ DEFAULT NOW()
);

-- Записи о согласиях
CREATE TABLE user_consents (
    id                BIGSERIAL PRIMARY KEY,
    user_id           BIGINT REFERENCES users(id) ON DELETE CASCADE,
    consent_type_id   INT REFERENCES consent_types(id),
    status            VARCHAR(20) NOT NULL, -- 'granted', 'denied', 'withdrawn'
    version_accepted  VARCHAR(20) NOT NULL,
    ip_address        INET,
    user_agent        TEXT,
    source            VARCHAR(100),  -- 'registration_form', 'account_settings'
    granted_at        TIMESTAMPTZ,
    withdrawn_at      TIMESTAMPTZ,
    expires_at        TIMESTAMPTZ,   -- некоторые согласия имеют срок
    UNIQUE (user_id, consent_type_id, version_accepted)
);

Сервис управления согласиями (Laravel)

class ConsentService
{
    public function grant(User $user, string $consentCode, string $source): UserConsent
    {
        $consentType = ConsentType::where('code', $consentCode)->firstOrFail();

        return UserConsent::updateOrCreate(
            [
                'user_id'          => $user->id,
                'consent_type_id'  => $consentType->id,
                'version_accepted' => $consentType->version,
            ],
            [
                'status'           => 'granted',
                'ip_address'       => request()->ip(),
                'user_agent'       => request()->userAgent(),
                'source'           => $source,
                'granted_at'       => now(),
                'withdrawn_at'     => null,
            ]
        );
    }

    public function withdraw(User $user, string $consentCode): void
    {
        $consentType = ConsentType::where('code', $consentCode)->firstOrFail();

        UserConsent::where('user_id', $user->id)
            ->where('consent_type_id', $consentType->id)
            ->where('status', 'granted')
            ->update([
                'status'       => 'withdrawn',
                'withdrawn_at' => now(),
            ]);

        // Действия при отзыве: отписать от рассылки, удалить профиль отслеживания
        event(new ConsentWithdrawn($user, $consentCode));
    }

    public function hasConsent(User $user, string $consentCode): bool
    {
        $consentType = ConsentType::where('code', $consentCode)->first();
        if (!$consentType) return false;

        return UserConsent::where('user_id', $user->id)
            ->where('consent_type_id', $consentType->id)
            ->where('status', 'granted')
            ->where('version_accepted', $consentType->version)
            ->exists();
    }
}

Форма согласия при регистрации

{{-- resources/views/auth/register.blade.php --}}
<form method="POST" action="/register">
    @csrf

    {{-- Обязательное согласие --}}
    <label class="required-consent">
        <input type="checkbox" name="consents[]" value="data_processing" required>
        Я согласен с
        <a href="/privacy-policy" target="_blank">политикой конфиденциальности</a>
        и даю согласие на обработку персональных данных
    </label>

    {{-- Опциональное --}}
    <label>
        <input type="checkbox" name="consents[]" value="marketing_email">
        Я хочу получать информацию об акциях и новостях на email
    </label>
</form>
// В RegisterController
protected function create(array $data): User
{
    $user = User::create([...]);

    $consentService = app(ConsentService::class);

    // Всегда даём согласие на базовую обработку
    $consentService->grant($user, 'data_processing', 'registration_form');

    // Опциональные — только если выбраны
    if (in_array('marketing_email', $data['consents'] ?? [])) {
        $consentService->grant($user, 'marketing_email', 'registration_form');
    }

    return $user;
}

Личный кабинет: управление согласиями

// ConsentSettings.tsx
export function ConsentSettings() {
    const { data: consents, mutate } = useSWR('/api/user/consents');

    const toggleConsent = async (code: string, currentStatus: boolean) => {
        await fetch(`/api/user/consents/${code}`, {
            method: 'PATCH',
            body: JSON.stringify({ granted: !currentStatus }),
        });
        mutate();
    };

    return (
        <div>
            <h2>Управление согласиями</h2>
            {consents?.map(consent => (
                <div key={consent.code}>
                    <div>
                        <strong>{consent.title}</strong>
                        <p>{consent.description}</p>
                        {consent.granted_at && (
                            <small>
                                Дано: {formatDate(consent.granted_at)}
                                {consent.withdrawn_at && `, отозвано: ${formatDate(consent.withdrawn_at)}`}
                            </small>
                        )}
                    </div>
                    {!consent.is_required && (
                        <Toggle
                            checked={consent.status === 'granted'}
                            onChange={() => toggleConsent(consent.code, consent.status === 'granted')}
                        />
                    )}
                </div>
            ))}
        </div>
    );
}

Re-consent при изменении политики

При изменении версии политики конфиденциальности пользователи с устаревшим согласием должны дать новое:

// Middleware: проверить актуальность обязательных согласий
class RequireFreshConsent
{
    public function handle(Request $request, Closure $next)
    {
        $user = $request->user();
        if (!$user) return $next($request);

        $hasOutdatedConsent = ConsentType::where('is_required', true)
            ->get()
            ->contains(function ($type) use ($user) {
                return !app(ConsentService::class)->hasConsent($user, $type->code);
            });

        if ($hasOutdatedConsent && !$request->is('consent*', 'logout*')) {
            return redirect()->route('consent.update');
        }

        return $next($request);
    }
}

Экспорт и удаление данных (право на забвение)

// Правая на доступ к данным (GDPR Art. 15)
class ExportUserDataCommand extends Command
{
    public function handle(): void
    {
        $user = User::findOrFail($this->argument('user_id'));

        $export = [
            'personal_data' => $user->only(['name', 'email', 'phone', 'created_at']),
            'consents'      => $user->consents()->with('type')->get(),
            'orders'        => $user->orders()->get(),
            'activity_log'  => AuditLog::where('user_id', $user->id)->get(),
        ];

        Storage::put("exports/user_{$user->id}.json", json_encode($export, JSON_PRETTY_PRINT));
    }
}

Срок реализации

  • Базовая модель согласий + форма регистрации: 3–4 дня
  • Личный кабинет управления + re-consent: 3–4 дня
  • API экспорта/удаления данных: 2–3 дня