
الـ JWT عبارة عن Secure Tokens بيتبعت مع كل Request أو Response عشان نتأكد ان البيانات بين الطرفين متغيرتش، كونها طريقة سهلة وفعالة بيخليها واحدة من أكثر الطرق المستخدمة في الـ User Authentication and Authorization (التحقق من هوية المستخدم و تحديد صلاحياته).
أجزاء الـ JWT
ال JWT بيتكون من 3 أجزاء:
- الـ Headers: ودي بيتكتب فيها نوع الـ Token و كذلك الـ Algorithm المستخدم.
- الـ Payload: ودا بيحتوي على معلومات المستخدم زي الـ Email و ممكن بعض صلاحياته وتاريخ اصدار وانتهاء الـ Token. والجزئين دول بيكونوا Base64 Encoded وتقدر تاخدهم و وتستعملهم في أي Base64 Decoder علي الانترنت و وهيظهرلك القيمة بداخلهم، وعشان كدا مينفعش نحط فيهم أي معلومات سرية زي الـ Passwords. 3. الـ Signature: والجزء دا بيكون عبارة عن Hashing للجزئين ( 1 + 2 + Secret )
💡والـ Secret ده الـ Server بس اللي يعرفه وكل لما كان أصعب كان قوة الـ JWT Token أكبر. وعادة ما بيتخزن في الـ Environment Variables في الـ Server ده.
طيب بنستفاد منه ازاي في الـ Authentication والـ Authorization؟
زمان عشان نعمل User Authentication كان بيتم بالخطوات دي:
- المستخدم بيعمل Login من خلال الـ Email والـ Password
- الـ Server بيتحقق منهم ويقوم بتحديد Session ID للمستخدم ويخزنها في الـ Database
- بعد كده الـ Server بيبعتها للمستخدم والمتصفح بيخزنها
- وفي كل Request المستخدم بيبعته للـ Server بيكون معاه الـ Session ID
هنا بنقابل مشكلتين:
- الـ Server كل مرة بيحتاج يتحقق من الـ Session ID بيبعت Request للـ Database ودا بيكلف Time وكمان Resources.
- الـ Sessions معرضة بسهولة لنوع من الـ Cyber Attacks اسمه Cross-Site Attacks
إنما الـ JWT Token بيتم بنفس الشكل دا مع الفارق ان الـ Server هنا مش هيخزنها عنده (زي ما واضح في الجزء الثاني من الصورة).
ازاي JWT حلت المشاكل دي ؟
الـ JWT بتحل المشكلة الأولى بكون الـ Server مبيضطرش يرجع للـ Database مع كل Request، الـ Server بكل بساطة بيعمل الآتي:
1- بيقوم حاسب الـ Hash للجزئين 1 و 2 باستخدام الـ Secret المخزنة عنده في الـ Environment Variables على سبيل المثال، والـ Hashing ده بيتم باستخدام الـ Algorithm المحدد في الـ Token في الـ Headers زي ماوضحنا. 2 – بيقوم بعمل مقارنة للناتج بالـ Signature اللي هي جزء الثالث من الـ JWT واللي المستخدم بعتها مع الـ Request.
وبكدا اتأكدنا من هوية المستخدم لأن أي تغيير في الجزئين الأول والثاني أو أي تلاعب في قيمة الـ Secret هينتج عنه Hash مختلف تمامًا عن الجزء الثالث.
اما بالنسبة المشكلة الثانية
فنقدر نحلها باننا نحط في الـ Payload نوع معين من ال Security Tokens اسمه (CSRF (Cross-Site Request Forgery اللي من خلاله بتأكد أن الـ Request ده اتبعت من نفس المكان مش من مكان تاني واقدر بنفس الطريقة اتأكد انه محصلش تلاعب بقيمة الـ Token دي.
الـ JWT سهلة الاستخدام والتطبيق في الـ Code لأن كل اللي بنعمله اننا بنستخدم Libraries جاهزة ونحدد الـ Secret اللي هنستخدمه.
وتقدروا تدخلوا على الموقع الرسمي لـ JWT وتجربوا الـ Decoder وتغيروا في القيم اللي في الـ Token.
مثال عملي على استخدام JWT
خلينا نشوف مثال عملي على كيفية إنشاء والتحقق من JWT في لغات برمجة مختلفة:
# Python (PyJWT)
import jwt
import datetime
SECRET = 'mysecretkey'
# إنشاء توكن
payload = {
'user_id': 123,
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
}
token = jwt.encode(payload, SECRET, algorithm='HS256')
print('JWT:', token)
# التحقق من التوكن
try:
decoded = jwt.decode(token, SECRET, algorithms=['HS256'])
print('Decoded:', decoded)
except jwt.ExpiredSignatureError:
print('Token expired')
except jwt.InvalidTokenError:
print('Invalid token')
في المثال ده:
- بننشئ JWT ونحدد بيانات المستخدم وتاريخ الانتهاء
- بنستخدم Secret للتحقق من صحة التوكن
- بنوضح كيفية التعامل مع انتهاء صلاحية التوكن أو كونه غير صالح