قم بتأمين واجهات برمجة تطبيقات Django REST Framework الخاصة بك بمصادقة قوية. قارن بين مصادقة الرمز المميز وتطبيق JWT (رمز JSON المميز)، بما في ذلك أمثلة عملية للتعليمات البرمجية وأفضل الممارسات.
مصادقة Python DRF: مقارنة بين تطبيق الرمز المميز و JWT لواجهات برمجة تطبيقات قوية
يعد تأمين واجهات برمجة التطبيقات الخاصة بك أمرًا بالغ الأهمية. عند إنشاء واجهات برمجة تطبيقات باستخدام Python و Django REST Framework (DRF)، لديك العديد من خيارات المصادقة المتاحة. تتعمق هذه المقالة في طريقتين شائعتين: مصادقة الرمز المميز ومصادقة JWT (رمز JSON المميز)، وتقارن نقاط القوة والضعف لديهما، وتقدم أمثلة عملية للتنفيذ.
فهم المصادقة في واجهات برمجة التطبيقات
المصادقة هي عملية التحقق من هوية المستخدم أو التطبيق الذي يصل إلى واجهة برمجة التطبيقات الخاصة بك. يضمن نظام المصادقة المنفذ بشكل جيد أن الكيانات المصرح لها فقط يمكنها الوصول إلى الموارد المحمية. في سياق واجهات برمجة تطبيقات RESTful، تتضمن المصادقة عادةً إرسال بيانات الاعتماد (على سبيل المثال، اسم المستخدم وكلمة المرور) مع كل طلب. ثم يتحقق الخادم من بيانات الاعتماد هذه، وإذا كانت صالحة، فإنه يمنح حق الوصول.
مصادقة الرمز المميز
مصادقة الرمز المميز هي آلية بسيطة ومباشرة. عندما يسجل المستخدم الدخول بنجاح، يقوم الخادم بإنشاء رمز مميز عشوائي فريد ويخزنه في قاعدة البيانات، ويربطه بالمستخدم. ثم يرسل العميل هذا الرمز المميز في رأس "Authorization" للطلبات اللاحقة. يسترجع الخادم الرمز المميز من قاعدة البيانات، ويتحقق من صحته، ويمنح حق الوصول وفقًا لذلك.
التنفيذ باستخدام DRF
يوفر DRF دعمًا مدمجًا لمصادقة الرمز المميز. إليك كيفية تنفيذه:
- قم بتثبيت DRF وتسجيله في مشروع Django الخاص بك:
أولاً، تأكد من تثبيت Django REST Framework:
pip install djangorestframework
ثم أضفه إلى `INSTALLED_APPS` في `settings.py`:
INSTALLED_APPS = [
...
'rest_framework',
]
- أضف نظام TokenAuthentication كفئة مصادقة افتراضية (اختياري، ولكن يوصى به):
في ملف `settings.py` الخاص بك، أضف ما يلي:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
}
سيؤدي هذا إلى تطبيق مصادقة الرمز المميز عالميًا عبر واجهة برمجة التطبيقات الخاصة بك. يتم تضمين `SessionAuthentication` للتفاعل المستند إلى المستعرض، ولكن يمكنك إزالته لتطبيق يعتمد على واجهة برمجة التطبيقات فقط.
- إنشاء رمز مميز لكل مستخدم:
يمكنك إنشاء رموز مميزة تلقائيًا للمستخدمين عند الإنشاء عن طريق إضافة معالج إشارة. قم بإنشاء ملف باسم `signals.py` في تطبيقك (على سبيل المثال، `users/signals.py`):
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
ثم قم باستيراد ملف `signals.py` هذا في ملف `users/apps.py` الخاص بك داخل طريقة `ready` لفئة تكوين التطبيق الخاص بك. مثال لـ `users/apps.py`:
from django.apps import AppConfig
class UsersConfig(AppConfig):
default_auto_field = 'django.db.BigAutoField'
name = 'users'
def ready(self):
import users.signals
الآن يمكنك إدارة الرموز باستخدام سطر الأوامر:
python manage.py drf_create_token <username>
- تنفيذ طرق عرض واجهة برمجة التطبيقات الخاصة بك:
إليك مثال بسيط لعرض يتطلب مصادقة الرمز المميز:
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.views import APIView
class ExampleView(APIView):
authentication_classes = [TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]
def get(self, request):
content = {
'message': 'Hello, ' + request.user.username + '! You are authenticated.',
}
return Response(content)
في هذا المثال، تحدد `authentication_classes` أنه يجب استخدام مصادقة الرمز المميز، وتحدد `permission_classes` أنه لا يمكن للمستخدمين المصادق عليهم فقط الوصول إلى العرض.
- تضمين عرض واجهة برمجة تطبيقات تسجيل الدخول:
تحتاج أيضًا إلى نقطة نهاية لإنشاء الرمز المميز عند تسجيل الدخول بنجاح:
from django.contrib.auth import authenticate
from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
@api_view(['POST'])
@permission_classes([AllowAny])
def login(request):
username = request.data.get('username')
password = request.data.get('password')
user = authenticate(username=username, password=password)
if user:
token, _ = Token.objects.get_or_create(user=user)
return Response({'token': token.key})
else:
return Response({'error': 'Invalid Credentials'}, status=status.HTTP_401_UNAUTHORIZED)
مزايا مصادقة الرمز المميز
- البساطة: سهولة التنفيذ والفهم.
- عديم الحالة: يحتوي كل طلب رمز مميز على معلومات تسمح له بالوقوف بمفرده.
عيوب مصادقة الرمز المميز
- الاعتماد على قاعدة البيانات: يتطلب البحث في قاعدة البيانات لكل طلب للتحقق من صحة الرمز المميز. يمكن أن يؤثر ذلك على الأداء، خاصة على نطاق واسع.
- إبطال الرمز المميز: يتطلب إبطال الرمز المميز حذفه من قاعدة البيانات، وهو ما قد يكون معقدًا.
- قابلية التوسع: قد لا يكون الحل الأكثر قابلية للتوسع لواجهات برمجة التطبيقات الكبيرة ذات حركة المرور العالية نظرًا لتكاليف قاعدة البيانات.
مصادقة JWT (رمز JSON المميز)
مصادقة JWT هي طريقة أكثر حداثة وتطوراً. JWT هو كائن JSON مضغوط وآمن على عنوان URL يحتوي على مطالبات حول المستخدم. يتم توقيع هذه المطالبات رقميًا باستخدام مفتاح سري أو زوج مفاتيح عام/خاص. عندما يسجل المستخدم الدخول، يقوم الخادم بإنشاء JWT وإرساله إلى العميل. ثم يقوم العميل بتضمين JWT هذا في رأس "Authorization" للطلبات اللاحقة. يمكن للخادم التحقق من توقيع JWT دون الحاجة إلى الوصول إلى قاعدة بيانات، مما يجعله حلاً أكثر كفاءة وقابلية للتوسع.
التنفيذ باستخدام DRF
لا يوفر DRF دعمًا مدمجًا لمصادقة JWT، ولكن العديد من المكتبات الممتازة تجعل من السهل دمجها. واحدة من أكثرها شعبية هي `djangorestframework-simplejwt`.
- تثبيت `djangorestframework-simplejwt`:
pip install djangorestframework-simplejwt
- تكوين إعدادات DRF:
في ملف `settings.py` الخاص بك، أضف ما يلي:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'ALGORITHM': 'HS256',
'SIGNING_KEY': settings.SECRET_KEY,
'VERIFYING_KEY': None,
'AUTH_HEADER_TYPES': ('Bearer',),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
}
شرح الإعدادات:
- `ACCESS_TOKEN_LIFETIME`: المدة التي يكون فيها رمز الوصول صالحًا (مثال، 5 دقائق).
- `REFRESH_TOKEN_LIFETIME`: المدة التي يكون فيها رمز التحديث صالحًا (مثال، يوم واحد). تُستخدم رموز التحديث للحصول على رموز وصول جديدة دون مطالبة المستخدم بتسجيل الدخول مرة أخرى.
- `ROTATE_REFRESH_TOKENS`: ما إذا كان سيتم تدوير رموز التحديث بعد كل استخدام.
- `BLACKLIST_AFTER_ROTATION`: ما إذا كان سيتم وضع رموز التحديث القديمة في القائمة السوداء بعد التدوير.
- `ALGORITHM`: الخوارزمية المستخدمة لتوقيع JWT (HS256 هو خيار شائع).
- `SIGNING_KEY`: المفتاح السري المستخدم لتوقيع JWT (عادةً مفتاح Django SECRET_KEY الخاص بك).
- `AUTH_HEADER_TYPES`: نوع رأس التفويض (عادةً "Bearer").
- تضمين طرق عرض واجهة برمجة تطبيقات تسجيل الدخول وتحديث الرمز المميز:
توفر `djangorestframework-simplejwt` طرق عرض للحصول على الرموز المميزة وتحديثها. قم بتضمينها في `urls.py` الخاص بك:
from django.urls import path
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns = [
path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
توفر `TokenObtainPairView` رموز الوصول والتحديث بعد المصادقة الناجحة. توفر `TokenRefreshView` رمز وصول جديد عند تزويده برمز تحديث صالح.
- تنفيذ طرق عرض واجهة برمجة التطبيقات الخاصة بك:
إليك مثال بسيط لعرض يتطلب مصادقة JWT:
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.authentication import JWTAuthentication
class ExampleView(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [permissions.IsAuthenticated]
def get(self, request):
content = {
'message': 'Hello, ' + request.user.username + '! You are authenticated.',
}
return Response(content)
على غرار مثال مصادقة الرمز المميز، تحدد `authentication_classes` أنه يجب استخدام مصادقة JWT، وتقيد `permission_classes` الوصول إلى المستخدمين المصادق عليهم فقط.
مزايا مصادقة JWT
- قابلية التوسع: لا يلزم البحث في قاعدة البيانات للتحقق من صحة الرمز المميز، مما يجعله أكثر قابلية للتوسع.
- عديم الحالة: يحتوي JWT على جميع المعلومات الضرورية للمصادقة.
- موحدة: JWT هو معيار معتمد على نطاق واسع، تدعمه العديد من المكتبات والمنصات.
- مناسبة للخدمات الصغيرة: مناسبة لبنى الخدمات الصغيرة، حيث يمكن للخدمات التحقق من JWTs بشكل مستقل.
عيوب مصادقة JWT
- التعقيد: أكثر تعقيدًا في التنفيذ من مصادقة الرمز المميز.
- حجم الرمز المميز: يمكن أن تكون JWTs أكبر من الرموز المميزة البسيطة، مما قد يزيد من استخدام النطاق الترددي.
- إبطال الرمز المميز: يعد إبطال JWT أمرًا صعبًا. بمجرد إصداره، يكون صالحًا حتى انتهاء صلاحيته. تتضمن الحلول البديلة وضع الرموز المميزة التي تم إبطالها في القائمة السوداء، مما يعيد إدخال تبعية قاعدة البيانات.
استراتيجيات إبطال الرمز المميز
تتطلب كل من طرق مصادقة الرمز المميز و JWT آليات لإبطال الوصول. إليك كيف يمكنك التعامل مع إبطال الرمز المميز:
إبطال مصادقة الرمز المميز
باستخدام مصادقة الرمز المميز، يكون الإبطال واضحًا ومباشرًا: ما عليك سوى حذف الرمز المميز من قاعدة البيانات:
from rest_framework.authtoken.models import Token
try:
token = Token.objects.get(user=request.user)
token.delete()
except Token.DoesNotExist:
pass
إبطال مصادقة JWT
يعد إبطال JWT أكثر تعقيدًا لأن الرمز المميز نفسه مكتفٍ ذاتيًا ولا يعتمد على البحث في قاعدة البيانات للتحقق من الصحة (في البداية). تتضمن الاستراتيجيات الشائعة ما يلي:
- القائمة السوداء للرموز المميزة: قم بتخزين الرموز المميزة التي تم إبطالها في قائمة سوداء (على سبيل المثال، جدول قاعدة بيانات أو ذاكرة تخزين مؤقت Redis). قبل التحقق من صحة JWT، تحقق مما إذا كان موجودًا في القائمة السوداء. يوفر `djangorestframework-simplejwt` دعمًا مدمجًا لوضع رموز التحديث في القائمة السوداء.
- أوقات انتهاء صلاحية قصيرة: استخدم أوقات انتهاء صلاحية قصيرة لرموز الوصول واعتمد على رموز التحديث للحصول على رموز وصول جديدة بشكل متكرر. يحد هذا من نافذة الفرصة لاستخدام رمز مميز تم اختراقه.
- تدوير رموز التحديث: قم بتدوير رموز التحديث بعد كل استخدام. سيؤدي هذا إلى إبطال الرموز القديمة في كل مرة ويمنع سرقة الرموز.
OAuth2 و OpenID Connect
بالنسبة لسيناريوهات المصادقة والترخيص الأكثر تعقيدًا، ضع في اعتبارك استخدام OAuth2 و OpenID Connect. توفر هذه المعايير إطارًا قويًا لتفويض الوصول إلى الموارد دون مشاركة بيانات الاعتماد. OAuth2 هو في الأساس بروتوكول ترخيص، بينما تعتمد OpenID Connect على OAuth2 لتوفير خدمات المصادقة. تعمل العديد من حزم Django، مثل `django-oauth-toolkit` و `django-allauth`، على تسهيل دمج OAuth2 و OpenID Connect في واجهات برمجة تطبيقات DRF الخاصة بك.
مثال على السيناريو: يريد المستخدم منح تطبيق تابع لجهة خارجية حق الوصول إلى بياناته المخزنة في واجهة برمجة التطبيقات الخاصة بك. باستخدام OAuth2، يمكن للمستخدم تفويض التطبيق دون مشاركة اسم المستخدم وكلمة المرور الخاصين به. بدلاً من ذلك، يتلقى التطبيق رمز وصول يمكنه استخدامه للوصول إلى بيانات المستخدم ضمن النطاق المحدد للأذونات.
اختيار طريقة المصادقة الصحيحة
تعتمد أفضل طريقة مصادقة على متطلباتك الخاصة:
- البساطة وسرعة التنفيذ: عادة ما يكون تنفيذ مصادقة الرمز المميز أسهل في البداية.
- قابلية التوسع: مصادقة JWT أكثر قابلية للتوسع لواجهات برمجة التطبيقات ذات حركة المرور العالية.
- متطلبات الأمان: ضع في اعتبارك حساسية بياناتك ومستوى الأمان المطلوب. توفر OAuth2/OpenID Connect ميزات الأمان الأكثر قوة ولكنها تتطلب تنفيذًا أكثر تعقيدًا.
- بنية الخدمات الصغيرة: تعتبر JWTs مناسبة تمامًا للخدمات الصغيرة، حيث يمكن لكل خدمة التحقق من الرموز المميزة بشكل مستقل.
أفضل الممارسات لمصادقة واجهة برمجة التطبيقات
- استخدام HTTPS: استخدم دائمًا HTTPS لتشفير الاتصال بين العميل والخادم، وحماية بيانات الاعتماد من التنصت.
- تخزين الأسرار بشكل آمن: لا تقم أبدًا بتخزين المفاتيح السرية أو كلمات المرور في نص عادي. استخدم متغيرات البيئة أو أدوات إدارة التكوين الآمنة.
- تنفيذ تحديد المعدل: قم بحماية واجهة برمجة التطبيقات الخاصة بك من سوء الاستخدام عن طريق تنفيذ تحديد المعدل لتقييد عدد الطلبات التي يمكن للعميل إجراؤها خلال فترة زمنية معينة.
- التحقق من صحة الإدخال: تحقق بدقة من صحة جميع بيانات الإدخال لمنع هجمات الحقن.
- المراقبة والتسجيل: راقب واجهة برمجة التطبيقات الخاصة بك بحثًا عن أي نشاط مشبوه وسجل أحداث المصادقة لأغراض التدقيق.
- تحديث المكتبات بانتظام: حافظ على تحديث Django و DRF ومكتبات المصادقة الخاصة بك للاستفادة من تصحيحات الأمان والتحسينات.
- تنفيذ CORS (مشاركة الموارد عبر المصادر): قم بتكوين CORS بشكل صحيح للسماح فقط للمجالات الموثوق بها بالوصول إلى واجهة برمجة التطبيقات الخاصة بك من متصفحات الويب.
الخلاصة
يعد اختيار طريقة المصادقة المناسبة أمرًا بالغ الأهمية لتأمين واجهات برمجة تطبيقات DRF الخاصة بك. توفر مصادقة الرمز المميز البساطة، بينما توفر مصادقة JWT قابلية التوسع والمرونة. إن فهم مزايا وعيوب كل طريقة، جنبًا إلى جنب مع أفضل الممارسات لأمان واجهة برمجة التطبيقات، سيمكنك من إنشاء واجهات برمجة تطبيقات قوية وآمنة تحمي بياناتك ومستخدميك.
تذكر أن تأخذ في الاعتبار احتياجاتك الخاصة واختر الحل الذي يحقق أفضل توازن بين الأمان والأداء وسهولة التنفيذ. استكشف OAuth2 و OpenID Connect لسيناريوهات الترخيص الأكثر تعقيدًا.