DSGVO-konforme Einwilligung technisch umsetzen – Consent Management | Enjyn Gruppe
Hallo Welt
Hallo Welt
Original Lingva Deutsch
Übersetzung wird vorbereitet...
Dieser Vorgang kann bis zu 60 Sekunden dauern.
Diese Seite wird erstmalig übersetzt und dann für alle Besucher gespeichert.
0%
DE Zurück zu Deutsch
Übersetzung durch Lingva Translate

303 Dokumentationen verfügbar

Wissensdatenbank

DSGVO Einwilligung Technisch Umsetzen

Zuletzt aktualisiert: 05.04.2026 um 19:42 Uhr

DSGVO-konforme Einwilligung technisch umsetzen – Consent Management

1. Rechtliche Anforderungen an die Einwilligung nach Art. 7 DSGVO

Artikel 7 DSGVO definiert die Anforderungen an eine gültige und wirksame Einwilligung. Diese muss folgende Bedingungen erfüllen:

1.1 Die 5 Kriterien für eine gültige Einwilligung:

Kriterium Bedeutung Technische Umsetzung
Freely Given
(Freiwillig)
Keine Zwangsmittel, keine Voraussetzung ohne Rechtsgrund, keine Nachteil ohne Nicht-Einwilligung Optional-Checkboxen (nicht verpflichtend für Nutzung). Bei essentiellen Services: klare Trennung
Specific
(Spezifisch)
Separate Einwilligung für jeden Zweck (nicht eine "Alles" Checkbox) Separate Checkboxen pro Cookie-Kategorie, Datennutzung oder Service
Informed
(Informiert)
Nutzer muss wissen, welche Daten wofür verarbeitet werden Klare, verständliche Erklärungen, Datenschutzerklärung verlinkt
Unambiguous
(Unmissverständlich)
Keine Zweideutigkeiten. Die Handlung muss klar Zustimmung signalisieren Explizite Checkboxen (nicht Opt-Out), klare Call-to-Action Buttons
Active
(Aktiv, Affirmative Action)
Keine vorgefüllten Boxen. Nutzer muss aktiv zustimmen Unkonfigurierte Checkboxen, keine automatische Aktivierung durch Scrolling
⚠️ Wichtig: Eine Einwilligung durch Weiterlesen der Website ("Implied Consent durch Scrollen") ist nicht gültig nach DSGVO. Der EuGH und die Aufsichtsbehörden sind hier streng: Nutzer müssen ein klares, bewusstes Zeichen geben.

2. Grundsätze der technischen Umsetzung

2.1 Consent BEFORE Processing

Nach Art. 7 Abs. 4 DSGVO muss die Einwilligung VOR der Datenverarbeitung erhoben werden. Das bedeutet:

  • Cookies werden erst nach Einwilligung gesetzt (außer essentiellen)
  • Google Analytics, Facebook Pixel, etc. werden erst nach Opt-In aktiviert
  • Externe Scripts werden erst nach Zustimmung geladen
  • Benutzer-Tracking beginnt nach Zustimmung

2.2 Granular Consent (Unabhängige Entscheidungen)

Nutzer sollen für jeden Zweck einzeln entscheiden können:

  • ☐ Essentiell (Funktioniert die Website)
  • ☐ Analytik (Google Analytics, Matomo)
  • ☐ Marketing (Facebook, Google Ads Pixel)
  • ☐ Externe Inhalte (YouTube, Vimeo, Twitter Embeds)
  • ☐ Partner/Drittanbieter

2.3 Logging und Audit Trail

Jede Einwilligung muss dokumentiert werden:

  • Zeitstempel der Einwilligung (ISO 8601 Format)
  • IP-Adresse des Nutzers (gehashed für Datenschutz)
  • Welche Zwecke wurden akzeptiert/abgelehnt
  • Version der Datenschutzerklärung/Consent-Richtlinie
  • Browser/Device-Info (optional, bei Bedarf)
  • Withdrawable-Möglichkeit dokumentieren
💡 Tipp: Speichern Sie Einwilligungen in Ihrem VVT (Verarbeitungsverzeichnis) als Verarbeitungstätigkeit: "Consent-Verwaltung für Marketing-Cookies". Dies ist selbst eine Datenverarbeitung und muss dokumentiert werden.

3. Datenbankschema für Einwilligungen

Hier ist ein praktisches SQL-Schema zur Speicherung von Einwilligungen:

CREATE TABLE consents (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,                           -- NULL für anonyme Nutzer
    email VARCHAR(255),                    -- Alternative zu user_id
    consent_hash VARCHAR(255) UNIQUE,      -- SHA256 Hash für Anonymisierung

    -- Einwilligung Zwecke (Boolean)
    consent_analytics BOOLEAN DEFAULT FALSE,
    consent_marketing BOOLEAN DEFAULT FALSE,
    consent_external_content BOOLEAN DEFAULT FALSE,
    consent_third_party BOOLEAN DEFAULT FALSE,

    -- Audit Trail
    timestamp_granted DATETIME,            -- Wann wurde zugestimmt
    timestamp_withdrawn DATETIME,          -- Wann wurde zurückgezogen (NULL = noch gültig)
    ip_address_hash VARCHAR(64),           -- Hash der IP, nicht die echte IP speichern!
    user_agent_hash VARCHAR(64),           -- Hash des Browsers
    consent_version VARCHAR(10),           -- z.B. "v1.0", "v2.0" für Versionierung

    -- Rechtliche Grundlagen
    gdpr_compliant BOOLEAN DEFAULT TRUE,
    legal_basis VARCHAR(50),               -- z.B. "Art. 6 Abs. 1 a) DSGVO"

    -- Nachverfolgung
    withdrawn_by VARCHAR(50),              -- "email", "unsubscribe_link", "api", "user_request"
    notes TEXT,                            -- Frei für Notizen

    INDEX idx_consent_hash (consent_hash),
    INDEX idx_email (email),
    INDEX idx_timestamp (timestamp_granted),
    INDEX idx_withdrawn (timestamp_withdrawn)
);

-- Historisierung (Optional aber empfohlen)
CREATE TABLE consents_audit_log (
    id INT AUTO_INCREMENT PRIMARY KEY,
    consent_id INT,
    old_analytics BOOLEAN,
    new_analytics BOOLEAN,
    changed_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    changed_by VARCHAR(255),
    FOREIGN KEY (consent_id) REFERENCES consents(id)
);

4. PHP Code: Einwilligung speichern und prüfen

<?php

// File: consent_manager.php

class ConsentManager {
    private $db;
    private $allowed_purposes = ['analytics', 'marketing', 'external_content', 'third_party'];

    public function __construct($database_connection) {
        $this->db = $database_connection;
    }

    /**
     * Speichere Einwilligung in Datenbank
     */
    public function saveConsent($email, $purposes, $ip_address) {
        // IP-Adresse hashen (nicht speichern!)
        $ip_hash = hash('sha256', $ip_address . $_SERVER['HTTP_USER_AGENT']);
        $user_agent_hash = hash('sha256', $_SERVER['HTTP_USER_AGENT']);
        $consent_hash = hash('sha256', $email . time() . rand());

        $stmt = $this->db->prepare("
            INSERT INTO consents (
                email, consent_analytics, consent_marketing,
                consent_external_content, consent_third_party,
                timestamp_granted, ip_address_hash, user_agent_hash,
                consent_version, consent_hash
            ) VALUES (?, ?, ?, ?, ?, NOW(), ?, ?, 'v2.0', ?)
        ");

        $stmt->bind_param(
            "siiiisss",
            $email,
            $purposes['analytics'] ? 1 : 0,
            $purposes['marketing'] ? 1 : 0,
            $purposes['external_content'] ? 1 : 0,
            $purposes['third_party'] ? 1 : 0,
            $ip_hash,
            $user_agent_hash,
            $consent_hash
        );

        if ($stmt->execute()) {
            // Audit Log
            $this->logConsentChange($stmt->insert_id, 'Created');

            // Cookie setzen (zur Demonstration)
            setcookie(
                'consent_preferences',
                $consent_hash,
                time() + (365 * 24 * 60 * 60),  // 1 Jahr
                '/',
                '',
                true,   // secure (HTTPS)
                true    // httpOnly
            );

            return ['success' => true, 'consent_id' => $stmt->insert_id];
        } else {
            return ['success' => false, 'error' => 'Database error'];
        }
    }

    /**
     * Prüfe, ob Nutzer Zustimmung für einen Zweck gegeben hat
     */
    public function hasConsent($email, $purpose) {
        if (!in_array($purpose, $this->allowed_purposes)) {
            return false;
        }

        $field = 'consent_' . $purpose;
        $stmt = $this->db->prepare("
            SELECT $field FROM consents
            WHERE email = ?
            AND timestamp_withdrawn IS NULL
            ORDER BY timestamp_granted DESC
            LIMIT 1
        ");

        $stmt->bind_param("s", $email);
        $stmt->execute();
        $result = $stmt->get_result()->fetch_assoc();

        return $result ? (bool)$result[$field] : false;
    }

    /**
     * Einwilligung zurückziehen
     */
    public function withdrawConsent($email, $purpose = null) {
        $stmt = $this->db->prepare("
            UPDATE consents
            SET timestamp_withdrawn = NOW()
            WHERE email = ? AND timestamp_withdrawn IS NULL
        ");

        $stmt->bind_param("s", $email);

        if ($stmt->execute()) {
            $this->logConsentChange(null, 'Withdrawn', $email);
            return ['success' => true, 'message' => 'Consent withdrawn'];
        }

        return ['success' => false];
    }

    /**
     * Audit Log entry
     */
    private function logConsentChange($consent_id, $action, $email = null) {
        $stmt = $this->db->prepare("
            INSERT INTO consents_audit_log (consent_id, changed_at, changed_by)
            VALUES (?, NOW(), ?)
        ");

        $stmt->bind_param("is", $consent_id, $action);
        $stmt->execute();
    }

    /**
     * Alle Einwilligungen eines Nutzers abrufen (für Transparenz)
     */
    public function getConsentForUser($email) {
        $stmt = $this->db->prepare("
            SELECT consent_analytics, consent_marketing,
                   consent_external_content, consent_third_party,
                   timestamp_granted, timestamp_withdrawn
            FROM consents
            WHERE email = ?
            ORDER BY timestamp_granted DESC
            LIMIT 1
        ");

        $stmt->bind_param("s", $email);
        $stmt->execute();
        return $stmt->get_result()->fetch_assoc();
    }
}

// Verwendungsbeispiel:
$db = new mysqli("localhost", "user", "password", "database");
$consent = new ConsentManager($db);

// Einwilligung speichern
$result = $consent->saveConsent(
    'user@example.com',
    ['analytics' => true, 'marketing' => false, 'external_content' => true, 'third_party' => false],
    $_SERVER['REMOTE_ADDR']
);

// Prüfen ob Nutzer Analytics akzeptiert hat
if ($consent->hasConsent('user@example.com', 'analytics')) {
    // Google Analytics laden
    echo '';
} else {
    echo '';
}

?>

5. Cookie Banner – Einfaches HTML/JS Beispiel (ohne Bibliothek)

<!-- Cookie Banner HTML -->
<div id="cookie-banner" style="
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: #f0f0f0;
    border-top: 3px solid #333;
    padding: 20px;
    z-index: 9999;
    font-family: Arial;
    box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
">
    <div style="max-width: 1200px; margin: 0 auto;">
        <h3>🍪 Datenschutz & Cookies</h3>
        <p>Wir nutzen Cookies für Analytics und Marketing. Lesen Sie unsere
        <a href="/datenschutz.html" target="_blank">Datenschutzerklärung</a></p>

        <div style="margin: 15px 0;">
            <label style="display: block; margin: 10px 0;">
                <input type="checkbox" id="essential" checked disabled>
                <strong>✓ Essentiell</strong> (Funktioniert die Website)
            </label>

            <label style="display: block; margin: 10px 0;">
                <input type="checkbox" id="analytics">
                <strong>Analytik</strong> (Google Analytics, Nutzungsverhalten verstehen)
            </label>

            <label style="display: block; margin: 10px 0;">
                <input type="checkbox" id="marketing">
                <strong>Marketing</strong> (Facebook Pixel, Retargeting)
            </label>

            <label style="display: block; margin: 10px 0;">
                <input type="checkbox" id="external">
                <strong>Externe Inhalte</strong> (YouTube, Twitter Embeds)
            </label>
        </div>

        <div style="margin-top: 15px;">
            <button id="accept-selected" style="
                background: #4CAF50;
                color: white;
                padding: 10px 20px;
                border: none;
                border-radius: 5px;
                cursor: pointer;
                margin-right: 10px;
            ">✓ Akzeptieren</button>

            <button id="accept-all" style="
                background: #008CBA;
                color: white;
                padding: 10px 20px;
                border: none;
                border-radius: 5px;
                cursor: pointer;
                margin-right: 10px;
            ">Alle akzeptieren</button>

            <button id="reject-all" style="
                background: #f44336;
                color: white;
                padding: 10px 20px;
                border: none;
                border-radius: 5px;
                cursor: pointer;
            ">Alles ablehnen</button>
        </div>
    </div>
</div>

<script>
// Cookie Banner JavaScript
const banner = document.getElementById('cookie-banner');
const acceptSelectedBtn = document.getElementById('accept-selected');
const acceptAllBtn = document.getElementById('accept-all');
const rejectAllBtn = document.getElementById('reject-all');

// Prüfe ob Einwilligung bereits vorhanden ist
if (document.cookie.includes('consent_preferences')) {
    banner.style.display = 'none';  // Banner ausblenden
}

// Accept Selected
acceptSelectedBtn.addEventListener('click', function() {
    const preferences = {
        analytics: document.getElementById('analytics').checked,
        marketing: document.getElementById('marketing').checked,
        external: document.getElementById('external').checked,
        essential: true  // Immer true
    };

    saveConsent(preferences);
    loadConsentScripts(preferences);
    banner.style.display = 'none';
});

// Accept All
acceptAllBtn.addEventListener('click', function() {
    const preferences = {
        analytics: true,
        marketing: true,
        external: true,
        essential: true
    };

    saveConsent(preferences);
    loadConsentScripts(preferences);
    banner.style.display = 'none';
});

// Reject All
rejectAllBtn.addEventListener('click', function() {
    const preferences = {
        analytics: false,
        marketing: false,
        external: false,
        essential: true
    };

    saveConsent(preferences);
    banner.style.display = 'none';
});

// Speichere Einwilligung (AJAX)
function saveConsent(preferences) {
    fetch('/api/save-consent.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            email: document.body.dataset.userEmail || 'anonymous@example.com',
            preferences: preferences
        })
    })
    .then(response => response.json())
    .then(data => {
        // Erfolg - Cookie setzen
        document.cookie = 'consent_preferences=' + data.consent_hash +
                         '; max-age=31536000; path=/; Secure; SameSite=Strict';
    });
}

// Lade Consent-abhängige Scripts
function loadConsentScripts(preferences) {
    if (preferences.analytics) {
        // Google Analytics
        window.dataLayer = window.dataLayer || [];
        window.gtag = function() { dataLayer.push(arguments); };
        gtag('js', new Date());
        gtag('config', 'GA-XXXXX');

        const script = document.createElement('script');
        script.src = 'https://www.googletagmanager.com/gtag/js?id=GA-XXXXX';
        script.async = true;
        document.head.appendChild(script);
    }

    if (preferences.marketing) {
        // Facebook Pixel
        !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
        n.callMethod.apply(n,arguments):n.queue.push(arguments)};n.push=n;n.loaded=!0;
        // ... Facebook Pixel Code ...
    }
}
</script>

6. Consent für Minors (Art. 8 DSGVO)

Für Nutzer unter 16 Jahren gelten in Deutschland zusätzliche Anforderungen:

  • Altersgrenze: Deutschland hat Art. 8 DSGVO auf 16 Jahre festgelegt (nicht 13 wie EU-Standard)
  • Eltern-Einwilligung erforderlich: Für Nutzer unter 16 Jahren müssen Eltern zustimmen
  • Altersverifikation: Websites müssen zumindest versuchen, das Alter zu überprüfen
  • Praktische Umsetzung: Meistens durch "Bestätigung, dass Sie 16+ Jahre alt sind" Checkbox
✅ Gut zu wissen: Für Kinder-Apps oder Kinder-Websites müssen Sie robustere Altersverifikation implementieren als nur eine Checkbox. Erwägen Sie API-basierte Altersverifikation (z.B. über Eltern-E-Mail-Bestätigung).

7. Vergleichstabelle: Einwilligung vs. Legale Grundlagen

Datenverarbeitung Einwilligung erforderlich? Alternative Rechtsgrundlagen Technische Umsetzung
Analytik-Cookies (Google Analytics) Ja (Art. 7 DSGVO) Nur mit robust anonymisierten Daten ohne Consent Cookie Banner mit Opt-In
Marketing-Cookies (Retargeting) Ja (Art. 7 DSGVO) Keine praktische Alternative Separate Marketing-Checkbox
Essentiell-Cookies (Session, CSRF) Nein Art. 6 Abs. 1 b) DSGVO (Vertrag) Können ohne Consent gesetzt werden
Newsletter-Abonnement Ja (Double-Opt-In empfohlen) Keine praktikable Alternative Bestätigung-Link per E-Mail
Kundendaten für Order-Processing Nein Art. 6 Abs. 1 b) DSGVO (Vertrag) Nicht verhinderbar bei Kauf
Profilierung/Personalisierung Ja (meistens) Ggf. legitimes Interesse mit Balancing Klare Erklärung + Zustimmung

8. Consent-Management-Plattformen (CMP)

Lösung Gebühren DSGVO-Compliance Features
Usercentrics 200-1000 EUR/Monat ✓ Zertifiziert Cookie-Scanner, Auto-Blocking, Multi-Region
Cookiebot (Cybot) 150-800 EUR/Monat ✓ Zertifiziert Auto-Detection, IAB TCF, GDPR-ready
Borlabs Cookie 99-249 EUR/Jahr (Lizenz) ✓ DSGVO-konform WordPress-Plugin, einfache Bedienung
OneTrust 500-5000 EUR/Monat ✓ Enterprise IAB TCF 2.0, Global Privacy Control, Governance
Open-Source (osano, CMPliance) Kostenlos (Hosting selbst) Depends auf Implementation Flexible, aber aufwändig

9. Cookie-Banner Checkliste für DSGVO-Compliance

Element Status Anmerkungen
Banner ist sichtbar und nicht zu verstecken ☐ Ja Muss sofort beim Laden sichtbar sein
Separate Checkboxen pro Cookie-Kategorie ☐ Ja Nicht eine große "Alles akzeptieren" Box
Keine vorgefüllten Checkboxen ☐ Ja Alle Checkboxen müssen leer sein
"Alles ablehnen" und "Ausgewählte akzeptieren" Button gleich prominent wie "Alle akzeptieren" ☐ Ja Keine versteckten Ablehnung-Buttons
Link zur Datenschutzerklärung ☐ Ja Muss leicht erreichbar sein
Essentiell-Cookies sind automatisch aktiviert (nicht Opt-Out) ☐ Ja Nur für wirklich notwendige Cookies
Einwilligung wird vor der Verarbeitung erhoben ☐ Ja Tracking-Scripts vor Consent ausblenden
Withdrawal-Möglichkeit (z.B. im Footer) ☐ Ja Nutzer können Consent leicht zurückziehen
Timestamp + Audit Log gespeichert ☐ Ja Nachweis für Compliance-Audits

10. A/B Testing und Consent Rates

Unternehmen dürfen ihre Cookie-Banner optimieren, aber nur im Rahmen von DSGVO-Compliance:

  • Erlaubt: Unterschiedliche Button-Farben testen, verschiedene Texte testen, Position testen
  • Nicht erlaubt: "Alles akzeptieren" Button mit dunkelgrünem, "Alles ablehnen" mit grauem Design (Nudging)
  • Nicht erlaubt: "Alles ablehnen" tiefer verstecken
  • Nicht erlaubt: Countdown-Timer ("In 10 Sekunden automatisch akzeptiert")

Das BGH und die Datenschutzbehörden handhaben dies streng. Die EuGH-Urteilssprechung (Planet49-Fall) und die Updates der EDPB-Guidelines sind klar: Jedes "Dark Pattern" ist untersagt.

11. Aufzeichnungspflichten für Einwilligungen

Was muss dokumentiert werden? Aufbewahrungsfrist Wer hat Zugriff?
Timestamp der Einwilligung Mind. 3 Jahre Datenschutzbeauftragter, Audit-Team
Welche Zwecke wurden akzeptiert/abgelehnt Mind. 3 Jahre Datenschutzbeauftragter, Audit-Team
Version der Consent-Erklärung Mind. 3 Jahre Datenschutzbeauftragter, Audit-Team
IP-Adresse (gehashed) Mind. 1 Jahr IT-Security
Rückzug-Informationen Mind. 3 Jahre Datenschutzbeauftragter, Audit-Team
⚠️ Wichtig: Das Löschen von Consent-Einträgen ist problematisch. Auch wenn Sie Personendaten löschen (Recht auf Vergessenheit), müssen Sie nachweisen können, dass Einwilligung vorhanden war. Dokumentieren Sie alle Löschungen mit Gründen.

12. Verwandte Dokumentationen


Zuletzt aktualisiert: April 2026 | Rechtsstand: DSGVO (EU 2016/679), BDSG (2018), EDPB-Guidelines | Diese Informationen stellen keine Rechtsberatung dar. Konsultieren Sie bei kritischen Fragen einen Datenschutzanwalt.

Enjix Beta

Enjyn AI Agent

Hallo 👋 Ich bin Enjix — wie kann ich dir helfen?
120