الأمان والأداء
خصوصية البيانات واللائحة العامة لحماية البيانات
خصوصية البيانات واللائحة العامة لحماية البيانات
تحدد اللائحة العامة لحماية البيانات (GDPR) معايير حماية البيانات والخصوصية في الاتحاد الأوروبي، مع تداعيات عالمية لتطبيقات الويب.
نظرة عامة على GDPR
مبادئ GDPR الرئيسية:
- المشروعية: أساس قانوني لمعالجة البيانات
- تقليل البيانات: جمع البيانات الضرورية فقط
- حد الغرض: استخدام البيانات فقط للأغراض المحددة
- الدقة: الحفاظ على البيانات دقيقة ومحدثة
- حد التخزين: حذف البيانات عندما لا تكون هناك حاجة إليها
- النزاهة والسرية: معالجة البيانات بشكل آمن
- المساءلة: إثبات الامتثال
تقليل البيانات
جمع المعلومات الأساسية فقط:
// ❌ سيء: جمع بيانات غير ضرورية
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('email');
$table->string('password');
$table->string('social_security_number'); // غير مطلوب!
$table->string('mother_maiden_name'); // غير مطلوب!
$table->date('birth_date'); // استخدم نطاق العمر بدلاً من ذلك
});
// ✅ جيد: جمع البيانات الأساسية
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('email');
$table->string('password');
$table->string('age_range'); // '18-24', '25-34', إلخ.
});
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('email');
$table->string('password');
$table->string('social_security_number'); // غير مطلوب!
$table->string('mother_maiden_name'); // غير مطلوب!
$table->date('birth_date'); // استخدم نطاق العمر بدلاً من ذلك
});
// ✅ جيد: جمع البيانات الأساسية
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('email');
$table->string('password');
$table->string('age_range'); // '18-24', '25-34', إلخ.
});
إدارة الموافقة
تنفيذ آليات الموافقة الصريحة:
// database/migrations/xxxx_add_consent_to_users.php
Schema::table('users', function (Blueprint $table) {
$table->boolean('marketing_consent')->default(false);
$table->boolean('analytics_consent')->default(false);
$table->timestamp('consent_date')->nullable();
$table->string('consent_ip')->nullable();
});
// app/Http/Controllers/ConsentController.php
public function updateConsent(Request $request)
{
$request->validate([
'marketing_consent' => 'boolean',
'analytics_consent' => 'boolean',
]);
auth()->user()->update([
'marketing_consent' => $request->marketing_consent,
'analytics_consent' => $request->analytics_consent,
'consent_date' => now(),
'consent_ip' => $request->ip(),
]);
return response()->json(['message' => 'تم تحديث الموافقة']);
}
Schema::table('users', function (Blueprint $table) {
$table->boolean('marketing_consent')->default(false);
$table->boolean('analytics_consent')->default(false);
$table->timestamp('consent_date')->nullable();
$table->string('consent_ip')->nullable();
});
// app/Http/Controllers/ConsentController.php
public function updateConsent(Request $request)
{
$request->validate([
'marketing_consent' => 'boolean',
'analytics_consent' => 'boolean',
]);
auth()->user()->update([
'marketing_consent' => $request->marketing_consent,
'analytics_consent' => $request->analytics_consent,
'consent_date' => now(),
'consent_ip' => $request->ip(),
]);
return response()->json(['message' => 'تم تحديث الموافقة']);
}
الحق في الحذف (الحق في النسيان)
السماح للمستخدمين بطلب حذف البيانات:
// app/Http/Controllers/DataDeletionController.php
public function requestDeletion(Request $request)
{
$user = auth()->user();
// إنشاء طلب حذف
DeletionRequest::create([
'user_id' => $user->id,
'status' => 'pending',
'requested_at' => now(),
]);
// إخطار المسؤولين
Mail::to(config('mail.admin'))
->send(new DataDeletionRequested($user));
return response()->json([
'message' => 'تم استلام طلب الحذف. سيتم معالجته خلال 30 يوماً.',
]);
}
public function processDeleteUser(User $user)
{
// إخفاء الهوية بدلاً من الحذف الصارم لتتبع التدقيق
$user->update([
'email' => 'deleted_' . $user->id . '@deleted.local',
'name' => '[مستخدم محذوف]',
'password' => Hash::make(Str::random(64)),
'deleted_at' => now(),
]);
// حذف البيانات الشخصية من الجداول ذات الصلة
$user->addresses()->delete();
$user->phoneNumbers()->delete();
$user->preferences()->delete();
}
public function requestDeletion(Request $request)
{
$user = auth()->user();
// إنشاء طلب حذف
DeletionRequest::create([
'user_id' => $user->id,
'status' => 'pending',
'requested_at' => now(),
]);
// إخطار المسؤولين
Mail::to(config('mail.admin'))
->send(new DataDeletionRequested($user));
return response()->json([
'message' => 'تم استلام طلب الحذف. سيتم معالجته خلال 30 يوماً.',
]);
}
public function processDeleteUser(User $user)
{
// إخفاء الهوية بدلاً من الحذف الصارم لتتبع التدقيق
$user->update([
'email' => 'deleted_' . $user->id . '@deleted.local',
'name' => '[مستخدم محذوف]',
'password' => Hash::make(Str::random(64)),
'deleted_at' => now(),
]);
// حذف البيانات الشخصية من الجداول ذات الصلة
$user->addresses()->delete();
$user->phoneNumbers()->delete();
$user->preferences()->delete();
}
مهم: يجب الاحتفاظ ببعض البيانات لأسباب قانونية/مالية (مثل سجلات المعاملات لمدة 7 سنوات). أخفِ هوية هذه البيانات بدلاً من حذفها.
تشفير البيانات
تشفير البيانات الحساسة عند التخزين:
use Illuminate\Support\Facades\Crypt;
// تشفير البيانات
$encrypted = Crypt::encryptString($user->social_security_number);
DB::table('users')->where('id', $user->id)
->update(['ssn_encrypted' => $encrypted]);
// فك تشفير البيانات
$decrypted = Crypt::decryptString($user->ssn_encrypted);
// استخدام التحويل المشفر في Laravel
class User extends Model
{
protected $casts = [
'ssn' => 'encrypted',
'credit_card' => 'encrypted',
];
}
// تشفير البيانات
$encrypted = Crypt::encryptString($user->social_security_number);
DB::table('users')->where('id', $user->id)
->update(['ssn_encrypted' => $encrypted]);
// فك تشفير البيانات
$decrypted = Crypt::decryptString($user->ssn_encrypted);
// استخدام التحويل المشفر في Laravel
class User extends Model
{
protected $casts = [
'ssn' => 'encrypted',
'credit_card' => 'encrypted',
];
}
الخصوصية حسب التصميم
بناء الخصوصية في بنية تطبيقك:
// مثال: انتهاء صلاحية البيانات التلقائي
// app/Console/Commands/DeleteExpiredData.php
class DeleteExpiredData extends Command
{
protected $signature = 'privacy:cleanup';
public function handle()
{
// حذف السجلات الأقدم من 90 يوماً
ActivityLog::where('created_at', '<', now()->subDays(90))
->delete();
// حذف الحسابات غير المؤكدة بعد 7 أيام
User::whereNull('email_verified_at')
->where('created_at', '<', now()->subDays(7))
->delete();
// إخفاء هوية الحسابات غير النشطة بعد 3 سنوات
User::where('last_login_at', '<', now()->subYears(3))
->each(fn($user) => $this->anonymizeUser($user));
}
}
// app/Console/Commands/DeleteExpiredData.php
class DeleteExpiredData extends Command
{
protected $signature = 'privacy:cleanup';
public function handle()
{
// حذف السجلات الأقدم من 90 يوماً
ActivityLog::where('created_at', '<', now()->subDays(90))
->delete();
// حذف الحسابات غير المؤكدة بعد 7 أيام
User::whereNull('email_verified_at')
->where('created_at', '<', now()->subDays(7))
->delete();
// إخفاء هوية الحسابات غير النشطة بعد 3 سنوات
User::where('last_login_at', '<', now()->subYears(3))
->each(fn($user) => $this->anonymizeUser($user));
}
}
الامتثال لملفات تعريف الارتباط
تنفيذ لافتة الموافقة على ملفات تعريف الارتباط:
<!-- لافتة الموافقة على ملفات تعريف الارتباط -->
<div id="cookie-banner" class="cookie-banner">
<p>نستخدم ملفات تعريف الارتباط لتحسين تجربتك.
<a href="/privacy-policy">اعرف المزيد</a></p>
<div class="cookie-buttons">
<button onclick="acceptAllCookies()">قبول الكل</button>
<button onclick="acceptEssentialOnly()">الضروري فقط</button>
<button onclick="showCookieSettings()">تخصيص</button>
</div>
</div>
<script>
function acceptAllCookies() {
setCookie('cookie_consent', 'all', 365);
enableAnalytics();
enableMarketing();
hideCookieBanner();
}
function acceptEssentialOnly() {
setCookie('cookie_consent', 'essential', 365);
hideCookieBanner();
}
</script>
<div id="cookie-banner" class="cookie-banner">
<p>نستخدم ملفات تعريف الارتباط لتحسين تجربتك.
<a href="/privacy-policy">اعرف المزيد</a></p>
<div class="cookie-buttons">
<button onclick="acceptAllCookies()">قبول الكل</button>
<button onclick="acceptEssentialOnly()">الضروري فقط</button>
<button onclick="showCookieSettings()">تخصيص</button>
</div>
</div>
<script>
function acceptAllCookies() {
setCookie('cookie_consent', 'all', 365);
enableAnalytics();
enableMarketing();
hideCookieBanner();
}
function acceptEssentialOnly() {
setCookie('cookie_consent', 'essential', 365);
hideCookieBanner();
}
</script>
تصدير البيانات (الحق في قابلية النقل)
السماح للمستخدمين بتنزيل بياناتهم:
// app/Http/Controllers/DataExportController.php
public function export(Request $request)
{
$user = auth()->user();
$data = [
'personal_info' => [
'name' => $user->name,
'email' => $user->email,
'created_at' => $user->created_at,
],
'orders' => $user->orders->toArray(),
'addresses' => $user->addresses->toArray(),
'preferences' => $user->preferences->toArray(),
];
return response()->json($data)
->header('Content-Disposition', 'attachment; filename="my_data.json"')
->header('Content-Type', 'application/json');
}
public function export(Request $request)
{
$user = auth()->user();
$data = [
'personal_info' => [
'name' => $user->name,
'email' => $user->email,
'created_at' => $user->created_at,
],
'orders' => $user->orders->toArray(),
'addresses' => $user->addresses->toArray(),
'preferences' => $user->preferences->toArray(),
];
return response()->json($data)
->header('Content-Disposition', 'attachment; filename="my_data.json"')
->header('Content-Type', 'application/json');
}
أفضل الممارسات: تعيين مسؤول حماية البيانات (DPO)، إجراء عمليات تدقيق منتظمة للخصوصية، الاحتفاظ بسجلات أنشطة المعالجة، وتنفيذ إجراءات الإخطار بالانتهاكات.
تمرين: راجع امتثال تطبيقك لـ GDPR. نفذ إدارة الموافقة ووظيفة تصدير البيانات وصفحة سياسة الخصوصية. اختبر سير عمل الحق في الحذف.