رموز JWT في PHP: دليل شامل للمصادقة والتفويض

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

رموز JWT في PHP: دليل شامل للتنفيذ

\n\n

JWT (JSON Web Token) هو معيار مفتوح (RFC 7519) لإنشاء رموز الوصول بناءً على تنسيق JSON. في PHP، يُستخدم JWT على نطاق واسع لتنفيذ المصادقة عديمة الحالة (stateless authentication) في REST API، والتطبيقات ذات الصفحة الواحدة (SPA)، والخدمات المصغرة.

\n\n

في هذه المقالة، سنشرح بالتفصيل كيفية العمل مع رموز JWT في PHP: بدءًا من تثبيت المكتبة إلى إنشاء الرموز والتحقق منها وتحديثها.

\n\n

ما هو JWT ولماذا هو مطلوب؟

\n\n

يتكون JWT من ثلاثة أجزاء مفصولة بنقاط:

\n\n
    \n
  • Header (الرأس) — يحتوي على نوع الرمز (JWT) وخوارزمية التوقيع (مثل HS256 أو RS256).
  • \n
  • Payload (الحمولة) — يحتوي على الادعاءات (claims): معرف المستخدم، الدور، وقت الإصدار (iat)، تاريخ انتهاء الصلاحية (exp) وبيانات أخرى.
  • \n
  • Signature (التوقيع) — يتم إنشاؤه عن طريق تجزئة الرأس والحمولة باستخدام مفتاح سري.
  • \n
\n\n

المزايا الرئيسية لـ JWT:

\n
    \n
  • لا يتطلب تخزين الجلسات على الخادم (stateless).
  • \n
  • يمكن أن يحتوي على أي بيانات (مثل دور المستخدم).
  • \n
  • يعمل مع نطاقات مختلفة وتطبيقات الجوال.
  • \n
  • يمكن التحقق منه بسهولة دون الرجوع إلى قاعدة البيانات.
  • \n
\n\n

تثبيت مكتبة firebase/php-jwt

\n\n

للعمل مع JWT في PHP، سنستخدم المكتبة الشهيرة firebase/php-jwt. يتم التثبيت عبر Composer:

\n\n
composer require firebase/php-jwt
\n\n

بعد التثبيت، سيظهر في المشروع التحميل التلقائي لـ Composer، والذي يجب تضمينه:

\n\n
require_once 'vendor/autoload.php';\n\nuse Firebase\\JWT\\JWT;\nuse Firebase\\JWT\\Key;
\n\n

إنشاء رمز JWT

\n\n

لإنشاء رمز، يجب تحديد مفتاح سري ($secretKey) وتشكيل الحمولة. مثال:

\n\n
use Firebase\\JWT\\JWT;\n\n$secretKey = 'your-256-bit-secret-key-here';\n$issuedAt = time();\n$expirationTime = $issuedAt + 3600; // الرمز صالح لمدة ساعة واحدة\n\n$payload = [\n    'iss' => 'pythonlib.ru',        // الناشر\n    'iat' => $issuedAt,             // وقت الإصدار\n    'exp' => $expirationTime,       // تاريخ انتهاء الصلاحية\n    'sub' => 123,                   // معرف المستخدم\n    'role' => 'admin'               // بيانات مخصصة\n];\n\n$jwt = JWT::encode($payload, $secretKey, 'HS256');\necho $jwt;
\n\n

ستكون النتيجة سلسلة مثل: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJweXRob25saWIucnUiLCJpYXQiOjE3Mjg0MDAwMDAsImV4cCI6MTcyODQwMzYwMCwic3ViIjoxMjMsInJvbGUiOiJhZG1pbiJ9.signature

\n\n

التحقق من JWT وفك تشفيره

\n\n

عند استلام رمز من العميل (على سبيل المثال، من الرأس Authorization: Bearer <token>)، يجب التحقق منه:

\n\n
use Firebase\\JWT\\JWT;\nuse Firebase\\JWT\\Key;\n\n$secretKey = 'your-256-bit-secret-key-here';\n$jwt = $_SERVER['HTTP_AUTHORIZATION'] ?? '';\n\ntry {\n    $decoded = JWT::decode($jwt, new Key($secretKey, 'HS256'));\n    $userId = $decoded->sub;\n    $role = $decoded->role;\n    \n    echo "المستخدم #{$userId} بدور {$role} مصرح به.";\n} catch (\\Exception $e) {\n    http_response_code(401);\n    echo "خطأ: " . $e->getMessage();\n}
\n\n

هام: تقوم المكتبة تلقائيًا بالتحقق من تاريخ انتهاء صلاحية الرمز (exp) ووقت الإصدار (iat). إذا كان الرمز منتهي الصلاحية أو غير صالح، سيتم طرح استثناء.

\n\n

تحديث JWT (Refresh Token)

\n\n

لتعزيز الأمان، عادةً ما تكون رموز JWT قصيرة العمر (15–60 دقيقة). للجلسات الطويلة، يُستخدم Refresh Token — وهو رمز منفصل يتم تخزينه في قاعدة البيانات ويسمح بالحصول على Access Token جديد دون إعادة إدخال اسم المستخدم وكلمة المرور.

\n\n

مثال على تنفيذ التحديث:

\n\n
function refreshAccessToken(string $ref                    

توصيات