عميل OAuth 2.0 بلغة C++ باستخدام cpp-httplib
\n\nفي تطوير البرمجيات الحديثة، أصبح التكامل مع الخدمات الخارجية عبر OAuth 2.0 معيارًا واقعيًا. بالنسبة للغة C++، التي ترتبط تقليديًا بالبرمجة النظامية، توجد عدة طرق لتنفيذ عميل OAuth. أحد الحلول الأكثر سهولة وفعالية هو مكتبة cpp-httplib — وهي مكتبة HTTP/HTTPS ذات ملف رأسي واحد، تتيح إنشاء تطبيقات الخادم والعميل دون تبعيات خارجية.
\n\nفي هذه المقالة، سنشرح كيفية استخدام cpp-httplib لبناء عميل OAuth 2.0 كامل يمكنه المصادقة عبر Google وGitHub وVK ومزودين آخرين. المادة موجهة لمبرمجي C++ الذين يرغبون في إضافة المصادقة إلى تطبيقات سطح المكتب أو التطبيقات المضمنة.
\n\nما هي cpp-httplib؟
\n\ncpp-httplib (المعروفة أيضًا باسم httplib.h) هي مكتبة ذات ملف رأسي واحد للغة C++11/14/17، كتبها Yuji Hirose. توفر واجهة برمجة تطبيقات بسيطة وبديهية لتنفيذ طلبات HTTP وإنشاء خوادم HTTP. تدعم SSL/TLS (عبر OpenSSL أو MbedTLS)، والبروكسي، وملفات تعريف الارتباط، والطلبات غير المتزامنة.
- \n
- ملف رأسي واحد — يكفي نسخ ملف واحد إلى المشروع. \n
- دعم HTTPS — اتصال آمن لـ OAuth. \n
- حجم صغير — حوالي 8000 سطر من الكود. \n
- متعدد المنصات — Windows، Linux، macOS، BSD. \n
بالنسبة لـ OAuth 2.0، سنحتاج إلى تنفيذ طلبات GET وPOST إلى نقاط نهاية المزود، بالإضافة إلى معالجة عمليات إعادة التوجيه. يتعامل cpp-httplib مع هذا بشكل ممتاز.
\n\nهندسة عميل OAuth 2.0 بلغة C++
\n\nيتضمن تدفق رمز التفويض النموذجي لـ OAuth 2.0 الخطوات التالية:
\n- \n
- يفتح التطبيق متصفح المستخدم مع رابط التفويض. \n
- يؤكد المستخدم الوصول. \n
- يعيد المزود التوجيه إلى رابط الاستدعاء مع رمز مؤقت. \n
- يستبدل التطبيق الرمز برمز الوصول. \n
- باستخدام الرمز، يتم تنفيذ الطلبات إلى API. \n
في C++، يمكننا تنفيذ ذلك عن طريق تشغيل خادم HTTP محلي (على cpp-httplib) لاعتراض الاستدعاء. بدلاً من ذلك، يمكن استخدام متصفح مدمج وتتبع الرابط عبر أحداث النظام، لكن نهج الخادم أبسط.
\n\nمثال على التنفيذ: OAuth عبر GitHub
\n\nلننظر إلى مثال كامل لعميل يقوم بالمصادقة عبر GitHub OAuth. للعمل، ستحتاج إلى تسجيل تطبيق OAuth على GitHub والحصول على Client ID وClient Secret.
\n\n#include <httplib.h>\n#include <iostream>\n#include <string>\n#include <thread>\n#include <regex>\n\n// الإعدادات\nconst std::string CLIENT_ID = "your_client_id";\nconst std::string CLIENT_SECRET = "your_client_secret";\nconst std::string REDIRECT_URI = "http://localhost:8080/callback";\nconst std::string AUTH_URL = "https://github.com/login/oauth/authorize";\nconst std::string TOKEN_URL = "https://github.com/login/oauth/access_token";\nconst std::string API_URL = "https://api.github.com/user";\n\nstd::string auth_code;\n\nvoid start_local_server() {\n httplib::Server svr;\n \n svr.Get("/callback", [&](const httplib::Request& req, httplib::Response& res) {\n // استخراج الكود من معاملات الاستعلام\n if (req.has_param("code")) {\n auth_code = req.get_param_value("code");\n res.set_content("<h2>تمت المصادقة بنجاح! أغلق النافذة.</h2>", "text/html");\n svr.stop();\n } else {\n res.set_content("<h2>خطأ في المصادقة</h2>", "text/html");\n }\n });\n \n std::cout << "الخادم يعمل على المنفذ 8080..." << std::endl;\n svr.listen("0.0.0.0", 8080);\n}\n\nint main() {\n // الخطوة 1: تكوين رابط التفويض\n std::string auth_url = AUTH_URL + "?clien