Впровадження управління согласіями на обробку даних на сайті
Управління согласіями (Consent Management) — система, яка фіксує, зберігає та обробляє юридично значущі согласи користувачів на обробку персональних даних відповідно до GDPR, 152-ФЗ та інших нормативних вимог.
Типи согласів
| Тип | Приклади | Обов'язковість |
|---|---|---|
| Обробка ПДн | Реєстрація, форма замовлення | Обов'язково |
| Маркетингові комунікації | Email-розсилка, SMS | За запитом |
| Профілювання | Рекомендації, аналітика | За запитом |
| Передача третім особам | Партнери, рекламні мережі | За запитом |
| Cookies (неосновні) | Аналітика, ремаркетинг | За запитом |
Структура бази даних
CREATE TABLE consent_types (
id SERIAL PRIMARY KEY,
code VARCHAR(50) UNIQUE NOT NULL,
title VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
version VARCHAR(20) NOT NULL,
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,
version_accepted VARCHAR(20) NOT NULL,
ip_address INET,
user_agent TEXT,
source VARCHAR(100),
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();
}
}
Форма согласу при реєстрації
<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>
Re-consent при зміні політики
При зміні версії політики конфіденціальності користувачі з застарілим согласом повинні дати нове:
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);
}
}
Тривалість реалізації
- Базова модель + форма реєстрації: 3–4 дні
- Особистий кабінет управління + re-consent: 3–4 дні
- API експорту/видалення даних: 2–3 дні







