كيفية دمج OAuth 2 في الواجهة الخلفية لـ Django / DRF دون الشعور بالجنون
نشرت: 2022-03-11كلنا كنا هناك. أنت تعمل على الواجهة الخلفية لواجهة برمجة التطبيقات ، وأنت سعيد بما يجري. لقد أكملت مؤخرًا الحد الأدنى من المنتج القابل للتطبيق (MVP) ، وقد اجتازت جميع الاختبارات ، وأنت تتطلع إلى تنفيذ بعض الميزات الجديدة.
ثم يرسل لك المدير رسالة بريد إلكتروني: "بالمناسبة ، نحتاج إلى السماح للأشخاص بتسجيل الدخول عبر Facebook و Google ؛ لا ينبغي عليهم إنشاء حساب لمجرد موقع صغير مثل موقعنا ".
رائعة. نطاق زحف الضربات مرة أخرى.
والخبر السار هو أن OAuth 2 قد برز كمعيار صناعي للمصادقة الاجتماعية ومصادقة الجهات الخارجية (المستخدمة بواسطة خدمات مثل Facebook و Google وما إلى ذلك) حتى تتمكن من التركيز على فهم هذا المعيار وتنفيذه لدعم مجموعة واسعة من الشبكات الاجتماعية موفرو المصادقة.
من المحتمل أنك لست معتادًا على OAuth 2 ؛ لم أكن كذلك ، عندما حدث هذا لي.
بصفتك مطور Python ، قد تقودك غريزتك إلى Pip ، أداة Python Package Index (PyPA) الموصى بها لتثبيت حزم Python. الأخبار السيئة هي أن النقطة تعرف حوالي 278 حزمة تتعامل مع OAuth - 53 منها تشير على وجه التحديد إلى Django. إنه عمل يستحق أسبوعًا فقط للبحث في الخيارات ، فما عليك سوى البدء في كتابة التعليمات البرمجية.
في هذا البرنامج التعليمي ، ستتعلم كيفية دمج OAuth 2 في إطار عمل Django أو Django Rest باستخدام Python Social Auth. على الرغم من أن هذه المقالة تركز على إطار عمل Django REST ، إلا أنه يمكنك تطبيق المعلومات المقدمة هنا لتطبيق نفس الشيء في مجموعة متنوعة من الأطر الخلفية الشائعة الأخرى.
نظرة عامة سريعة على تدفق OAuth 2
تم تصميم OAuth 2 من البداية كبروتوكول مصادقة الويب. هذا ليس هو نفسه تمامًا كما لو كان قد تم تصميمه كبروتوكول مصادقة صافي ؛ يفترض أن أدوات مثل عرض HTML وإعادة توجيه المتصفح متاحة لك.
من الواضح أن هذا يمثل عائقًا أمام واجهة برمجة تطبيقات تستند إلى JSON ، ولكن يمكنك التغلب على هذا الأمر.
ستخوض العملية كما لو كنت تكتب موقعًا تقليديًا من جانب الخادم.
تدفق OAuth 2 من جانب الخادم
تحدث الخطوة الأولى خارج نطاق التطبيق بالكامل. يجب على مالك المشروع تسجيل تطبيقك لدى كل موفر OAuth 2 تحتاج إلى تسجيلات الدخول له.
أثناء هذا التسجيل ، يزودون موفر OAuth 2 بمعرف URI لمعاودة الاتصال ، حيث سيكون طلبك متاحًا لتلقي الطلبات. في المقابل ، يحصلون على مفتاح العميل وسر العميل . يتم تبادل هذه الرموز أثناء عملية المصادقة للتحقق من طلبات تسجيل الدخول.
تشير الرموز المميزة إلى رمز الخادم الخاص بك على أنه العميل. المضيف هو موفر OAuth 2. ليست مخصصة لعملاء API الخاص بك.
يبدأ التدفق عندما ينشئ تطبيقك صفحة تتضمن زرًا ، مثل "تسجيل الدخول باستخدام Facebook" أو "تسجيل الدخول باستخدام Google+". في الأساس ، هذه ليست سوى روابط بسيطة ، يشير كل منها إلى عنوان URL مثل ما يلي:
https://oauth2provider.com/auth? response_type=code& client_id=CLIENT_KEY& redirect_uri=CALLBACK_URI& scope=profile& scope=email
(ملاحظة: تم إدراج فواصل الأسطر في URI أعلاه لسهولة القراءة.)
لقد قدمت مفتاح العميل وأعدت توجيه URI ، لكن لا توجد أسرار. في المقابل ، أخبرت الخادم أنك تريد رمز مصادقة ردًا على ذلك والوصول إلى نطاقي "الملف الشخصي" و "البريد الإلكتروني". تحدد هذه النطاقات الأذونات التي تطلبها من المستخدم ، وتحد من تفويض رمز الوصول الذي تتلقاه.
عند الاستلام ، يتم توجيه متصفح المستخدم إلى صفحة ديناميكية يتحكم فيها موفر OAuth 2. يتحقق موفر OAuth 2 من تطابق عنوان URI لرد الاتصال ومفتاح العميل مع بعضهما البعض قبل المتابعة. إذا حدث ذلك ، فسيختلف التدفق لفترة وجيزة اعتمادًا على الرموز المميزة لجلسة المستخدم.
إذا لم يقم المستخدم بتسجيل الدخول إلى هذه الخدمة حاليًا ، فسيُطلب منه القيام بذلك. بمجرد تسجيل الدخول ، يظهر للمستخدم مربع حوار يطلب الإذن للسماح لتطبيقك بتسجيل الدخول.
بافتراض موافقة المستخدم ، يقوم خادم OAuth 2 بإعادة توجيههم مرة أخرى إلى عنوان URI لمعاودة الاتصال الذي قدمته ، بما في ذلك رمز التفويض في معامِلات طلب البحث: GET https://api.yourapp.com/oauth2/callback/?code=AUTH_CODE
.
رمز التفويض هو رمز مميز وسريع الصلاحية للاستخدام مرة واحدة ؛ فور استلامه ، يجب أن يستدير خادمك ، ويقدم طلبًا آخر إلى موفر OAuth 2 ، بما في ذلك رمز التفويض وسر العميل:
POST https://oauth2provider.com/token/? grant_type=authorization_code& code=AUTH_CODE& redirect_uri=CALLBACK_URI& client_id=CLIENT_KEY& client_secret=CLIENT_SECRET
الغرض من رمز التفويض هذا هو مصادقة طلب POST أعلاه ، ولكن نظرًا لطبيعة التدفق ، يجب توجيهه عبر نظام المستخدم. على هذا النحو ، فهو غير آمن بطبيعته.
القيود المفروضة على رمز التفويض (أي أنه تنتهي صلاحيته بسرعة ويمكن استخدامه مرة واحدة فقط) موجودة للتخفيف من المخاطر الكامنة في تمرير بيانات اعتماد المصادقة من خلال نظام غير موثوق به.
هذه المكالمة ، التي يتم إجراؤها مباشرة من الخادم الخاص بك إلى خادم موفر OAuth 2 ، هي المكون الرئيسي لعملية تسجيل الدخول من جانب الخادم لـ OAuth 2. يعني التحكم في المكالمة أنك تعرف أن المكالمة مؤمنة بواسطة TLS ، مما يساعد على حمايتها من هجمات التنصت على المكالمات الهاتفية.
يضمن تضمين رمز التفويض منح المستخدم الموافقة صراحةً. يضمن تضمين سر العميل ، الذي لا يراه المستخدمون أبدًا ، أن هذا الطلب لا ينشأ من بعض الفيروسات أو البرامج الضارة الموجودة على نظام المستخدم ، والتي اعترضت رمز التفويض.
إذا كان كل شيء متطابقًا ، فسيعيد الخادم رمز وصول ، يمكنك من خلاله إجراء مكالمات إلى هذا الموفر أثناء مصادقته باعتبارك المستخدم.
بمجرد استلام رمز الوصول من الخادم ، يقوم الخادم بإعادة توجيه متصفح المستخدم مرة أخرى إلى الصفحة المقصودة للمستخدمين الذين قاموا بتسجيل الدخول للتو. من الشائع الاحتفاظ برمز الوصول في ذاكرة التخزين المؤقت لجلسة المستخدم من جانب الخادم ، لذلك أن الخادم يمكنه إجراء مكالمات إلى المزود الاجتماعي المحدد عند الضرورة.
يجب ألا يكون رمز الوصول متاحًا للمستخدم أبدًا!
هناك المزيد من التفاصيل التي يمكننا الغوص فيها.
على سبيل المثال ، تتضمن Google رمزًا مميزًا للتحديث يطيل من عمر رمز الوصول الخاص بك بينما يوفر Facebook نقطة نهاية يمكنك من خلالها استبدال رموز الوصول قصيرة العمر بشيء أطول. هذه التفاصيل لا تهمنا ، لأننا لن نستخدم هذا التدفق.
هذا التدفق مرهق لواجهة برمجة تطبيقات REST. على الرغم من أنه يمكنك جعل عميل الواجهة الأمامية يقوم بإنشاء صفحة تسجيل الدخول الأولية وجعل الواجهة الخلفية توفر عنوان URL لمعاودة الاتصال ، إلا أنك ستواجه مشكلة في النهاية. تريد إعادة توجيه المستخدم إلى الصفحة المقصودة للواجهة الأمامية بمجرد استلام رمز الوصول ، ولا توجد طريقة REST واضحة للقيام بذلك.
لحسن الحظ ، يتوفر تدفق OAuth 2 آخر ، والذي يعمل بشكل أفضل في هذه الحالة.
تدفق OAuth 2 من جانب العميل
في هذا التدفق ، تصبح الواجهة الأمامية مسؤولة عن معالجة عملية OAuth 2 بأكملها. يشبه بشكل عام التدفق من جانب الخادم ، مع استثناء مهم - تظهر الواجهات الأمامية مباشرة على الأجهزة التي يتحكم فيها المستخدمون ، لذلك لا يمكن تكليفهم بسر العميل. الحل ببساطة هو التخلص من هذه الخطوة بأكملها من العملية.
الخطوة الأولى ، كما هو الحال في التدفق من جانب الخادم ، هي تسجيل التطبيق.
في هذه الحالة ، لا يزال مالك المشروع يسجل التطبيق ، ولكن كتطبيق ويب. سيظل موفر OAuth 2 يوفر مفتاح العميل ، ولكن قد لا يقدم أي سر للعميل.
توفر الواجهة الأمامية للمستخدم زر تسجيل الدخول الاجتماعي ، والذي يوجه إلى صفحة ويب يتحكم موفر OAuth 2 فيها ، ويطلب إذنًا لتطبيقنا للوصول إلى جوانب معينة من ملف تعريف المستخدم.
يبدو عنوان URL مختلفًا بعض الشيء هذه المرة على الرغم من:
https://oauth2provider.com/auth? response_type=token& client_id=CLIENT_KEY& redirect_uri=CALLBACK_URI& scope=profile& scope=email
لاحظ أن معلمة response_type
هذه المرة في عنوان URL هي token
.
فماذا عن إعادة توجيه URI؟
هذا ببساطة هو أي عنوان على الواجهة الأمامية يتم إعداده للتعامل مع رمز الوصول بشكل مناسب.
اعتمادًا على مكتبة OAuth 2 المستخدمة ، قد تقوم الواجهة الأمامية فعليًا بتشغيل خادم قادر على قبول طلبات HTTP على جهاز المستخدم بشكل مؤقت ؛ في هذه الحالة ، يكون عنوان URL لإعادة التوجيه بالشكل http://localhost:7862/callback/?token=TOKEN
.
نظرًا لأن خادم OAuth 2 يعرض إعادة توجيه HTTP بعد قبول المستخدم ، وتتم معالجة إعادة التوجيه هذه بواسطة المتصفح الموجود على جهاز المستخدم ، يتم تفسير هذا العنوان بشكل صحيح ، مما يمنح وصول الواجهة الأمامية إلى الرمز المميز.
بدلاً من ذلك ، قد تنفذ الواجهة الأمامية صفحة مناسبة مباشرةً. في كلتا الحالتين ، تكون الواجهة الأمامية مسؤولة ، في هذه المرحلة ، عن تحليل معلمات الاستعلام ومعالجة رمز الوصول.
من هذه النقطة فصاعدًا ، يمكن للواجهة الأمامية الاتصال مباشرة بواجهة برمجة تطبيقات موفر OAuth 2 باستخدام الرمز المميز. لكن المستخدمين لا يريدون ذلك حقًا ؛ يريدون الوصول المصدق إلى API الخاص بك. كل ما تحتاجه الواجهة الخلفية هو نقطة نهاية يمكن للواجهة الأمامية من خلالها تبادل رمز وصول موفر اجتماعي لرمز يمنحك الوصول إلى واجهة برمجة التطبيقات الخاصة بك.
لماذا نسمح بذلك على الإطلاق ، بالنظر إلى أن توفير رمز الوصول للواجهة الأمامية هو بطبيعته أقل أمانًا من التدفق من جانب الخادم؟

يسمح التدفق من جانب العميل بفصل أكثر صرامة بين الواجهة الخلفية REST API والواجهة الأمامية التي تواجه المستخدم. لا يوجد شيء يمنعك بشكل صارم من تحديد خادمك الخلفي باعتباره URI لإعادة التوجيه ؛ سيكون التأثير النهائي نوعًا من التدفق الهجين.
تكمن المشكلة في أنه يجب على الخادم بعد ذلك إنشاء صفحة مناسبة للمستخدم ، ثم إعادة التحكم مرة أخرى إلى الواجهة الأمامية بطريقة ما.
من الشائع في المشاريع الحديثة فصل الاهتمامات بدقة بين واجهة المستخدم الأمامية والواجهة الخلفية التي تتعامل مع منطق الأعمال. يتواصلون عادةً عبر واجهة برمجة تطبيقات JSON محددة جيدًا. إن التدفق الهجين الموصوف أعلاه يفسد أن فصل الاهتمامات ، على الرغم من ذلك ، يجبر النهاية الخلفية على خدمة صفحة مواجهة للمستخدم ، ثم تصميم بعض التدفق للتحكم اليدوي بطريقة ما إلى الواجهة الأمامية.
يُعد السماح للواجهة الأمامية بمعالجة رمز الوصول تقنية ملائمة تحافظ على فصل الاهتمامات. إنه يزيد إلى حد ما من المخاطر من العميل المخترق ، لكنه يعمل بشكل جيد بشكل عام.
قد يبدو هذا التدفق معقدًا بالنسبة للواجهة الأمامية ، وهو كذلك ، إذا طلبت من فريق الواجهة الأمامية تطوير كل شيء بمفردهم. ومع ذلك ، يوفر كل من Facebook و Google مكتبات تمكّن الواجهة الأمامية من تضمين أزرار تسجيل الدخول التي تتعامل مع العملية بأكملها بأقل قدر من التكوين.
فيما يلي وصفة لتبادل الرموز في النهاية الخلفية.
في ظل تدفق العميل ، تكون النهاية الخلفية معزولة تمامًا عن عملية OAuth 2. لا تنخدع: هذه ليست مهمة بسيطة. ستحتاج إلى دعم الوظائف التالية على الأقل.
- أرسل طلبًا واحدًا على الأقل إلى موفر OAuth 2 ، فقط للتأكد من أن الرمز المميز الذي قدمته الواجهة الأمامية صالح ، وليس سلسلة عشوائية عشوائية.
- عندما يكون الرمز المميز صالحًا ، قم بإرجاع رمز مميز صالح لواجهة برمجة التطبيقات الخاصة بك. خلاف ذلك ، قم بإرجاع خطأ إعلامي.
- إذا كان هذا مستخدمًا جديدًا ، فأنشئ نموذج
User
له ، وقم بتعبئته بشكل مناسب. - إذا كان هذا مستخدمًا له نموذج
User
بالفعل ، فقم بمطابقته بعنوان بريده الإلكتروني ، حتى يتمكن من الوصول إلى الحساب الحالي الصحيح بدلاً من إنشاء حساب جديد لتسجيل الدخول الاجتماعي. - قم بتحديث تفاصيل ملف تعريف المستخدم بناءً على ما قدموه على وسائل التواصل الاجتماعي.
والخبر السار هو أن تنفيذ كل هذه الوظائف على النهاية الخلفية أسهل بكثير مما قد تتوقعه.
إليك السحر في كيفية جعل كل هذا يعمل في النهاية الخلفية في عشرين سطرًا فقط من التعليمات البرمجية. يعتمد هذا على مكتبة Python Social Auth ("PSA" من الآن فصاعدًا) ، لذلك ستحتاج إلى تضمين كل social-auth-core
و social-auth-app-django
في requirements.txt
. txt.
ستحتاج أيضًا إلى تكوين المكتبة كما هو موثق هنا. لاحظ أن هذا يستثني معالجة بعض الاستثناءات من أجل الوضوح.
يمكن العثور على الكود الكامل لهذا المثال هنا.
@api_view(http_method_names=['POST']) @permission_classes([AllowAny]) @psa() def exchange_token(request, backend): serializer = SocialSerializer(data=request.data) if serializer.is_valid(raise_exception=True): # This is the key line of code: with the @psa() decorator above, # it engages the PSA machinery to perform whatever social authentication # steps are configured in your SOCIAL_AUTH_PIPELINE. At the end, it either # hands you a populated User model of whatever type you've configured in # your project, or None. user = request.backend.do_auth(serializer.validated_data['access_token']) if user: # if using some other token back-end than DRF's built-in TokenAuthentication, # you'll need to customize this to get an appropriate token object token, _ = Token.objects.get_or_create(user=user) return Response({'token': token.key}) else: return Response( {'errors': {'token': 'Invalid token'}}, status=status.HTTP_400_BAD_REQUEST, )
لا يوجد سوى القليل الذي يجب إدخاله في إعداداتك (الرمز الكامل) ، وبعد ذلك تكون جاهزًا:
AUTHENTICATION_BACKENDS = ( 'social_core.backends.google.GoogleOAuth2', 'social_core.backends.facebook.FacebookOAuth2', 'django.contrib.auth.backends.ModelBackend', ) for key in ['GOOGLE_OAUTH2_KEY', 'GOOGLE_OAUTH2_SECRET', 'FACEBOOK_KEY', 'FACEBOOK_SECRET']: # Use exec instead of eval here because we're not just trying to evaluate a dynamic value here; # we're setting a module attribute whose name varies. exec("SOCIAL_AUTH_{key} = os.environ.get('{key}')".format(key=key)) SOCIAL_AUTH_PIPELINE = ( 'social_core.pipeline.social_auth.social_details', 'social_core.pipeline.social_auth.social_uid', 'social_core.pipeline.social_auth.auth_allowed', 'social_core.pipeline.social_auth.social_user', 'social_core.pipeline.user.get_username', 'social_core.pipeline.social_auth.associate_by_email', 'social_core.pipeline.user.create_user', 'social_core.pipeline.social_auth.associate_user', 'social_core.pipeline.social_auth.load_extra_data', 'social_core.pipeline.user.user_details', )
أضف تعيينًا لهذه الوظيفة في urls.py
، وبذلك تكون جاهزًا!
كيف يعمل هذا السحر؟
تعد Python Social Auth قطعة رائعة جدًا ومعقدة جدًا من الآلات. إنه لمن دواعي سرورنا تمامًا التعامل مع المصادقة والوصول إلى أي من العشرات من مزودي المصادقة الاجتماعية ، وهو يعمل على معظم أطر ويب Python الشائعة ، بما في ذلك Django و Flask و Pyramid و CherryPy و WebPy.
بالنسبة للجزء الأكبر ، الكود أعلاه عبارة عن طريقة عرض تستند إلى وظيفة إطار عمل Django REST (DRF) القياسية جدًا: فهي تستمع لطلبات POST على أي مسار تعينه إليه في urls.py
، بافتراض أنك ترسله طلبًا في الشكل الذي تتوقعه ، ثم تحصل على كائن User
، أو None
.
إذا حصلت على كائن User
، فسيكون من نوع النموذج الذي قمت بتكوينه في مكان آخر في مشروعك ، والذي قد يكون موجودًا أو غير موجود بالفعل. اهتمت PSA بالفعل بالتحقق من صحة الرمز المميز ، وتحديد ما إذا كان هناك تطابق للمستخدم أم لا ، وإنشاء مستخدم إذا لزم الأمر ، وتحديث تفاصيل المستخدم من المزود الاجتماعي.
يتم تحديد التفاصيل الدقيقة لكيفية تعيين المستخدم من مستخدم مزود الخدمة الاجتماعية إلى مستخدمك ، وربطه بالمستخدمين الحاليين ، بواسطة SOCIAL_AUTH_PIPELINE
المحدد أعلاه. هناك الكثير لتتعلمه حول كيفية عمل كل هذا ، لكنه خارج نطاق هذا المنشور. يمكنك قراءة المزيد عنه هنا.
الجزء الأساسي من السحر هو مصمم الديكور @psa()
على العرض ، والذي يضيف بعض الأعضاء إلى كائن request
الذي يتم تمريره إلى العرض الخاص بك. الشيء الأكثر إثارة للاهتمام بالنسبة لنا هو request.backend
(إلى PSA ، الواجهة الخلفية هي أي مزود مصادقة اجتماعية).
تم اختيار النهاية الخلفية المناسبة لنا وإلحاقها بكائن request
بناءً على وسيطة backend
العرض ، والتي يتم ملؤها بواسطة عنوان URL نفسه.
بمجرد أن يكون لديك كائن backend
في متناول اليد ، سيكون من دواعي سرورنا تمامًا مصادقتك على هذا الموفر ، بالنظر إلى رمز الوصول الخاص بك ؛ هذه هي طريقة do_auth
. وهذا بدوره يشرك SOCIAL_AUTH_PIPELINE
بالكامل من ملف التكوين الخاص بك.
يمكن لخط الأنابيب القيام ببعض الأشياء القوية جدًا إذا قمت بتوسيعه ، على الرغم من أنه يقوم بالفعل بكل ما تحتاجه بدون أي شيء سوى وظيفته الافتراضية المضمنة.
بعد ذلك ، عاد للتو إلى رمز DRF العادي: إذا حصلت على كائن User
صالح ، فيمكنك بسهولة إرجاع رمز API مناسب. إذا لم تسترد كائن User
صالحًا ، فمن السهل إنشاء خطأ.
أحد عيوب هذه التقنية هو أنه على الرغم من أنه من السهل نسبيًا إرجاع الأخطاء في حالة حدوثها ، إلا أنه من الصعب الحصول على الكثير من الأفكار حول الخطأ الذي حدث على وجه التحديد. تبتلع PSA أي تفاصيل قد يعرضها الخادم حول المشكلة.
ثم مرة أخرى ، من طبيعة أنظمة المصادقة المصممة جيدًا أن تكون غامضة إلى حد ما بشأن مصادر الخطأ. إذا قال أحد التطبيقات للمستخدم "كلمة مرور غير صالحة" بعد محاولة تسجيل الدخول ، فهذا يعادل القول "تهانينا! لقد خمنت اسم مستخدم صالحًا ".
لماذا لا تقوم فقط بتدوير الخاصة بك؟
باختصار: القابلية للتمدد. عدد قليل جدًا من موفري OAuth 2 الاجتماعيين يطلبون أو يعرضون نفس المعلومات تمامًا في استدعاءات واجهة برمجة التطبيقات الخاصة بهم بالطريقة نفسها تمامًا. ومع ذلك ، هناك جميع أنواع الحالات الخاصة والاستثناءات.
إن إضافة موفر اجتماعي جديد بمجرد أن تقوم بالفعل بإعداد PSA هو أمر يتعلق ببضعة أسطر من التكوين في ملفات الإعدادات الخاصة بك. ليس عليك تعديل أي كود على الإطلاق. تلخص PSA كل ذلك ، بحيث يمكنك التركيز على التطبيق الخاص بك.
كيف يمكنني اختبار ذلك على الأرض؟
سؤال جيد! unittest.mock
ليس مناسبًا تمامًا للاستهزاء باستدعاءات API المدفونة تحت طبقة تجريد عميقة داخل مكتبة ؛ مجرد اكتشاف المسار الدقيق للسخرية يتطلب جهدًا كبيرًا.
بدلاً من ذلك ، نظرًا لأن PSA مبني على قمة مكتبة الطلبات ، فإنك تستخدم مكتبة الردود الممتازة للاستهزاء بالمقدمين على مستوى HTTP.
المناقشة الكاملة للاختبار خارج نطاق هذه المقالة ، ولكن تم تضمين عينة من اختباراتنا هنا. وظائف خاصة يجب mocked
هي مدير السياق الذي تم الاستهزاء به وفئة SocialAuthTests
.
دع PSA يقوم برفع الأحمال الثقيلة.
عملية OAuth2 مفصلة ومعقدة مع الكثير من التعقيد المتأصل. لحسن الحظ ، من الممكن تجاوز الكثير من هذا التعقيد من خلال جلب مكتبة مخصصة للتعامل معه بطريقة غير مؤلمة قدر الإمكان.
يقوم Python Social Auth بعمل رائع في ذلك. لقد أظهرنا طريقة عرض Django / DRF التي تستخدم تدفق OAuth2 من جانب العميل ، الضمني ، للحصول على إنشاء مستخدم سلس ومطابقة في 25 سطرًا فقط من التعليمات البرمجية. هذا ليس رث جدا.