Реализация механизма отзыва согласия на обработку данных
По GDPR (статья 7.3) пользователь должен иметь возможность отозвать согласие так же легко, как дать его. Если согласие давалось через одно нажатие кнопки, отзыв не должен требовать 10 шагов.
Точки отзыва согласия
- Настройки аккаунта (раздел "Приватность" / "Мои данные")
- Footer-ссылка "Управление cookie"
- Email с unsubscribe-ссылкой
- Кнопка повторного открытия cookie-баннера
Реализация управления в кабинете
// PrivacySettings.jsx
function PrivacySettings() {
const [consent, setConsent] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
fetch('/api/my/consent')
.then(r => r.json())
.then(data => { setConsent(data.current); setLoading(false) })
}, [])
const updateConsent = async (category, value) => {
const updated = { ...consent, [category]: value }
await fetch('/api/my/consent', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ categories: updated })
})
setConsent(updated)
// Применить немедленно
if (!value && category === 'analytics') {
window['ga-disable-G-XXXXXXXX'] = true
}
}
const revokeAll = async () => {
if (!confirm('Вы уверены? Это не удаляет ваш аккаунт, только согласие на дополнительную обработку.')) return
await fetch('/api/my/consent', { method: 'DELETE' })
setConsent({ necessary: true, analytics: false, marketing: false })
}
if (loading) return <Spinner />
return (
<div className="privacy-settings">
<h2>Управление данными</h2>
{Object.entries({
analytics: 'Аналитика и улучшение сервиса',
marketing: 'Персонализированная реклама',
preferences: 'Запоминание предпочтений'
}).map(([key, label]) => (
<label key={key} className="consent-toggle">
<span>{label}</span>
<input
type="checkbox"
checked={consent?.[key] ?? false}
onChange={e => updateConsent(key, e.target.checked)}
/>
</label>
))}
<button className="btn-danger" onClick={revokeAll}>
Отозвать все согласия
</button>
<a href="#" onClick={() => window.CookieBot?.renew()}>
Изменить настройки cookie
</a>
</div>
)
}
Серверная обработка отзыва
@app.route('/api/my/consent', methods=['PUT'])
@login_required
def update_consent():
new_categories = request.json['categories']
# Записать в лог
consent_logger.log(
request,
categories=new_categories,
event_type='updated',
user_id=current_user.id
)
# Применить изменения немедленно
if not new_categories.get('marketing'):
unsubscribe_from_marketing(current_user.id)
remove_from_ad_audiences(current_user.email)
return jsonify({'status': 'updated', 'categories': new_categories})
def unsubscribe_from_marketing(user_id: int):
user = db.get_user(user_id)
# Mailchimp
mailchimp_client.lists.update_list_member_tags(
list_id=MAILCHIMP_LIST_ID,
subscriber_hash=md5(user.email.lower()),
body={'tags': [{'name': 'marketing_opted_out', 'status': 'active'}]}
)
# Отключить рекламные пиксели для этого пользователя
db.execute("""
UPDATE users SET marketing_opted_out = true,
marketing_opt_out_at = NOW()
WHERE id = %s
""", (user_id,))
Cookie-баннер: повторное открытие
// Ссылка в footer: "Управление cookie"
document.getElementById('cookie-settings-link').addEventListener('click', (e) => {
e.preventDefault()
// Cookiebot
if (window.CookieBot) {
window.CookieBot.renew()
return
}
// CookieYes
if (window.revisitCkyConsent) {
window.revisitCkyConsent()
return
}
// Кастомный баннер
ConsentBanner.show()
})
Email-отписка (one-click unsubscribe)
RFC 8058 — одноклик отписка для email маркетинга:
@app.route('/unsubscribe')
def unsubscribe():
token = request.args.get('token')
category = request.args.get('category', 'marketing')
user_id = verify_unsubscribe_token(token)
if not user_id:
return "Недействительная ссылка", 400
# Немедленный отзыв
consent_logger.log(
request,
categories={category: False},
event_type='withdrawn',
user_id=user_id,
method='email_unsubscribe'
)
unsubscribe_from_marketing(user_id)
return render_template('unsubscribed.html', category=category)
Срок выполнения
Реализация UI управления согласиями в кабинете + серверная обработка отзыва + интеграция с email-системой — 2–3 рабочих дня.







