GDPR 合規
規則
- 實作資料刪除端點(刪除權):應要求刪除或匿名化所有使用者 PII
- 使用時間戳追蹤明確同意:記錄使用者同意的內容、時間及政策版本
- 在分析與日誌中匿名化 PII:使用不透明 ID,絕不儲存原始電子郵件或姓名
- 實作資料匯出端點(可攜性權):以 JSON 或 CSV 格式回傳所有使用者資料
- 顯示 Cookie 同意橫幅:在使用者選擇加入前,不載入任何追蹤腳本
- 在每個含有資料收集表單的頁面上,連結至隱私權政策
- 維護 PII 存取稽核日誌:記錄誰在何時檢視了哪些個人資料
- 72 小時違規通知:準備好文件化的流程與聯絡人清單
app.delete("/api/user/data", requireAuth, async (req, res) => {
const userId = req.user.id;
await db.transaction(async (tx) => {
await tx.delete(userProfiles).where(eq(userProfiles.userId, userId));
await tx.delete(userSessions).where(eq(userSessions.userId, userId));
await tx.update(users).set({
email: `deleted_${userId}@anonymized.local`,
name: "Deleted User",
deletedAt: new Date(),
}).where(eq(users.id, userId));
});
await auditLog("user_data_deleted", { userId, requestedBy: userId });
res.json({ success: true });
});
const consentSchema = z.object({
marketing: z.boolean(),
analytics: z.boolean(),
policyVersion: z.string(),
});
app.post("/api/consent", requireAuth, async (req, res) => {
const consent = consentSchema.parse(req.body);
await db.insert(consentRecords).values({
userId: req.user.id,
...consent,
consentedAt: new Date(),
ipAddress: req.ip,
});
res.json({ success: true });
});
避免事項
- 軟刪除使用者資料但未實際移除 PII — 「已刪除」使用者的電子郵件仍留在資料庫中
- 在取得 Cookie 同意前載入 Google Analytics 或追蹤像素
- 在分析事件或應用程式日誌中儲存原始電子郵件
- 缺少資料匯出機制 — 使用者對其資料擁有合法權利
- 假設 GDPR 僅適用於歐盟公司 — 實際上,任何服務歐盟使用者的應用程式都需遵守