关于 cnil-cookie-banner
面向为法国用户实现 Cookie 横幅的团队,提供 CNIL 合规的界面与技术要求,重点包括同等拒绝选项、按用途细分同意、标签阻止和无障碍设计。
主要功能
- 01接受与拒绝按钮同等醒目
- 02按用途单独设置同意
- 03非必要选项默认关闭
- 04同意过期或政策变更时重新提示
- 05同意前阻止非必要标签
- 06支持键盘与屏幕阅读器
适用场景
- 01实现分层 Cookie 横幅
- 02配置按用途的同意记录
- 03检查同意前的标签加载行为
- 04审查横幅的无障碍支持
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mukul975/ privacy-data-protection-skills --skill cnil-cookie-banner安装后在 Claude Code 中输入/cnil-cookie-banner确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/template.mdreferences/standards.mdworkflows.mdscripts/process.py详细介绍
符合 CNIL 要求的 Cookie 横幅实现
概述
法国国家信息与自由委员会(Commission Nationale de l'Informatique et des Libertés,CNIL)执行欧盟最严格的 Cookie 同意要求之一。根据其更新后的指南(2020 年 9 月 17 日第 2020-091 号审议决定)及具有里程碑意义的执法行动——包括 2021 年 12 月 31 日对 Google LLC 处以 1 亿欧元罚款、对 Google Ireland Limited 处以 5,000 万欧元罚款,以及 2022 年 12 月 31 日对 Meta Platforms Ireland Limited 处以 6,000 万欧元罚款(之后在后续行动中进一步提高,多项决定合计罚款 1.5 亿欧元)——面向法国用户提供服务的组织必须实施符合特定设计和功能要求的 Cookie 横幅。
CNIL Cookie 横幅要求
1. 接受和拒绝选项的显著程度相同
CNIL 要求,拒绝 Cookie 的操作必须与接受 Cookie 一样简单。这是 Google 和 Meta 执法行动中的核心问题:两家公司都提供了醒目的“全部接受”按钮,却要求用户点击多次才能拒绝 Cookie。
Pinnacle E-Commerce Ltd 的合规设计:
+------------------------------------------------------------------+
| Pinnacle E-Commerce uses cookies |
| |
| We use cookies to improve your shopping experience, analyse |
| site traffic, and personalise content. You can accept all |
| cookies, reject non-essential cookies, or customise your |
| choices. |
| |
| [Accept All] [Reject All] [Customise] |
| |
| Privacy Policy | Cookie Policy |
+------------------------------------------------------------------+
设计规则:
- “全部接受”和“全部拒绝”按钮的视觉权重必须相同:尺寸、字体、配色方案和层级位置均相同
- 任何一个按钮都不得使用暗黑模式(例如,“接受”按钮使用醒目颜色,“拒绝”按钮使用灰色)
- 同一层级还必须提供“自定义”或“管理偏好设置”选项
- 横幅不得使用操纵性措辞(例如,“接受以获得最佳体验”与中性的“全部拒绝”)
2. 不得设置 Cookie 墙
根据 CNIL 指南,不得以接受 Cookie 作为访问网站的条件。Cookie 墙——即在用户接受所有 Cookie 之前屏蔽内容——属于禁止行为。
禁止的实现方式:
+------------------------------------------------------------------+
| To access Pinnacle E-Commerce, please accept our cookies. |
| |
| [Accept All Cookies] |
+------------------------------------------------------------------+
合规替代方案: 用户点击“全部拒绝”后,网站必须仍可完全正常使用(至少可浏览)。购物车功能、身份验证和安全所需的必要 Cookie,仍可根据严格必要豁免规则设置。
3. 按用途进行细粒度同意
自定义层必须允许用户分别同意每种用途:
第 2 层 — 自定义偏好设置:
+------------------------------------------------------------------+
| Manage your cookie preferences |
| |
| Strictly Necessary [Always Active] |
| Required for the site to function (cart, security, login). |
| These cannot be disabled. |
| |
| Analytics [Toggle OFF] |
| Help us understand how visitors use the site to improve our |
| services. Data is aggregated and anonymised. |
| Partners: Google Analytics |
| |
| Advertising [Toggle OFF] |
| Used to show you relevant advertisements on other websites. |
| Partners: Meta, Google Ads |
| |
| Functionality [Toggle OFF] |
| Remember your preferences such as language and currency. |
| |
| [Confirm My Choices] [Accept All] [Reject All] |
+------------------------------------------------------------------+
第 2 层规则:
- 所有非必要选项默认关闭(不得预先勾选以表示同意)
- 每个类别都列出具体的第三方合作方名称
- “确认我的选择”会保存当前选项状态
- 此层级也必须保留“全部接受”和“全部拒绝”选项
4. 同意有效期与重新征求同意
CNIL 建议定期更新同意:
| 参数 | CNIL 要求 |
|---|---|
| 同意最长有效期 | 6 个月(CNIL 建议) |
| 拒绝状态保留期 | 重新提示前保留 6 个月 |
| 同意证明保留期 | 同意有效期加适用的诉讼时效 |
| 同意过期后重新提示 | 横幅必须自动重新显示 |
| Cookie 政策变更后重新提示 | 必须——需要重新取得同意 |
Pinnacle E-Commerce Ltd 的实现方式:
将同意时间戳存储在第一方 Cookie 中:
cookie_consent_timestamp=2026-01-15T10:30:00Z
cookie_consent_version=v2.3
cookie_consent_state=accepted_analytics|rejected_advertising|accepted_functionality
每次页面加载时,检查:
- 是否存在
cookie_consent_timestamp? - 其时间是否在 6 个月以内?
cookie_consent_version是否与当前 Cookie 政策版本一致?
如果任一项检查未通过,则重新显示横幅。
5. 不得采用欺骗性设计模式
CNIL 明确禁止以下暗黑模式:
| 暗黑模式 | 说明 | 禁止原因 |
|---|---|---|
| 按钮设计不对称 | 接受按钮大且醒目,拒绝按钮小且呈灰色 | 突出程度不平等,违反同等便捷要求 |
| 隐藏拒绝选项 | 拒绝选项藏在多层设置中 | 必须与接受选项处于同一层级 |
| 令人困惑的开关 | 开关的视觉效果让人误以为已开启,实际却处于关闭状态 | 损害知情同意 |
| 诱导内疚 | “拒绝后,您将错过个性化优惠” | 属于操纵性语言 |
| 预先选定用途 | 分析或功能开关预先启用 | 违反主动同意要求(Planet49) |
| 反复提示 | 用户拒绝后,每次访问页面都重新显示横幅 | 属于胁迫;必须在 6 个月内尊重拒绝决定 |
技术实现
横幅加载行为
- 同意前不得设置 Cookie:用户与横幅交互前,不得设置非必要 Cookie。必须在容器层级阻止标签。
- 同步加载横幅:同意横幅必须先于任何标签管理脚本加载。
- 服务端执行:对于会触发设置 Cookie 的请求,应在服务端验证同意状态。
标签阻止架构
Page Load
│
├── Load consent banner script (synchronous)
│
├── Check consent state cookie
│ ├── No consent recorded → Show banner, block all non-essential tags
│ ├── Consent expired (>6 months) → Show banner, block all non-essential tags
│ ├── Consent recorded → Parse consent state
│ ├── Analytics accepted → Fire GA4 tags
│ ├── Advertising accepted → Fire Meta Pixel, Google Ads tags
│ └── Functionality accepted → Fire preference cookies
│
└── User interacts with banner
├── Accept All → Set all tags, store consent
├── Reject All → Block all non-essential tags, store refusal
└── Customise → Show Layer 2, await per-purpose selection
同意存储
存储同意证明时,至少包含以下字段:
| 字段 | 值 |
|---|---|
| 同意 ID | 每次同意事件对应一个 UUID |
| 用户标识符 | 假名化的用户 ID 或 Cookie ID |
| 时间戳 | ISO 8601 UTC |
| 横幅版本 | 横幅文本/设计的哈希值 |
| Cookie 政策版本 | 版本标识符(例如 v2.3) |
| 决定 | 按用途记录接受/拒绝 |
| 收集机制 | "cookie_banner_layer_1" 或 "cookie_banner_layer_2" |
| IP 地址 | 用于地理位置验证(单独保留并限制访问) |
无障碍要求
Cookie 横幅必须符合 WCAG 2.1 AA 级:
- 可通过键盘导航(Tab、Enter、Escape)
- 兼容屏幕阅读器(ARIA 角色、标签)
- 颜色对比度充足(最低比例为 4.5:1)
- 焦点在交互前限制于横幅内(防止与后方页面交互)
- 横幅文本字号至少为 14px
CNIL 执法先例
| 日期 | 机构 | 罚款 | 主要违规行为 |
|---|---|---|---|
| 31 Dec 2021 | Google LLC | EUR 100,000,000 | 未提供同等的拒绝机制;在获得同意前设置 Cookie |
| 31 Dec 2021 | Google Ireland | EUR 50,000,000 | 与 Google LLC 相同的违规行为 |
| 29 Dec 2022 | TikTok | EUR 5,000,000 | 未提供同等的拒绝机制 |
| 31 Dec 2022 | Meta Platforms Ireland | EUR 60,000,000 | 未提供同等的拒绝机制 |
| 15 Jun 2023 | Criteo | EUR 40,000,000 | 同意并非自由作出;信息不充分 |
| 28 Dec 2023 | Amazon France | EUR 32,000,000 | 未经同意即写入 Cookie |
主要法律参考
- CNIL Deliberation No. 2020-091 (17 September 2020) — 关于 Cookie 和其他跟踪器的指南
- CNIL Recommendation on cookies (1 October 2020) — 收集同意的实际操作方式
- ePrivacy Directive 2002/58/EC, Article 5(3) — 在设备上存储/访问信息须获得同意
- CJEU Case C-673/17 (Planet49) — 主动同意,不得预先勾选复选框
- GDPR Article 7 — 同意的条件,包括撤回同意
- CNIL Decision SAN-2021-023 (Google) — 因 Cookie 同意违规被处以总计 EUR 150M 罚款
- CNIL Decision SAN-2022-021 (Meta) — 因 Cookie 同意违规被处以 EUR 60M 罚款