OAuth 2.0 لتطبيقات الويب من جهة العميل

يشرح هذا المستند طريقة تنفيذ تفويض OAuth 2.0 للوصول إلى Google APIs من تطبيق ويب JavaScript. يسمح OAuth 2.0 للمستخدمين بمشاركة بيانات محددة مع أحد التطبيقات مع الحفاظ على خصوصية أسماء المستخدمين وكلمات المرور والمعلومات الأخرى. على سبيل المثال، يمكن لتطبيق أن يستخدم OAuth 2.0 للحصول على إذن من المستخدمين لتخزين الملفات في Google Drive.

ويُطلق على مسار OAuth 2.0 هذا اسم مسار المنح الضمنية. وقد صُممت هذه الخدمة للتطبيقات التي يمكنها الوصول إلى واجهات برمجة التطبيقات فقط أثناء وجود المستخدم في التطبيق. ولا يمكن لهذه التطبيقات تخزين معلومات سرية.

في هذه العملية، يفتح تطبيقك عنوان URL على Google يستخدم مَعلمات طلب البحث لتحديد تطبيقك ونوع الوصول إلى واجهة برمجة التطبيقات الذي يتطلبه التطبيق. يمكنك فتح عنوان URL في نافذة المتصفّح الحالية أو في نافذة منبثقة. يمكن للمستخدم المصادقة مع Google ومنح الأذونات المطلوبة. بعد ذلك، يُعيد محرّك بحث Google توجيه المستخدم إلى تطبيقك. تتضمن عملية إعادة التوجيه رمز دخول يتحقّق منه تطبيقك ويستخدمه بعد ذلك في تقديم طلبات البيانات من واجهة برمجة التطبيقات.

مكتبة برامج Google APIs وخدمات هوية Google

إذا كنت تستخدم مكتبة برامج Google APIs للغة JavaScript لإجراء استدعاءات مصرّح بها إلى Google، عليك استخدام مكتبة JavaScript في Google Identity Services للتعامل مع مسار OAuth 2.0. يُرجى الاطّلاع على نموذج الرمز المميّز لتطبيق "خدمات الهوية من Google"، والذي يستند إلى خطوات المنح الضمني لبروتوكول OAuth 2.0.

المتطلبات الأساسية

تفعيل واجهات برمجة التطبيقات لمشروعك

ويجب تفعيل واجهات برمجة التطبيقات هذه في API Consoleلأي تطبيق يستدعي Google APIs.

لتفعيل واجهة برمجة تطبيقات لمشروعك:

  1. Open the API Library في Google API Console.
  2. If prompted, select a project, or create a new one.
  3. تعرض قائمة " API Library " جميع واجهات برمجة التطبيقات المتاحة، ويتم تجميعها حسب مجموعة المنتجات ومدى رواجها. إذا كانت واجهة برمجة التطبيقات التي تريد تفعيلها غير مرئية في القائمة، استخدِم البحث للعثور عليها، أو انقر على عرض الكل في مجموعة المنتجات التي تنتمي إليها.
  4. اختر واجهة برمجة التطبيقات التي تريد تفعيلها، ثم انقر على الزر تفعيل.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

إنشاء بيانات اعتماد التفويض

يجب أن يمتلك أي تطبيق يستخدم OAuth 2.0 للوصول إلى Google APIs بيانات اعتماد التفويض التي تحدّد التطبيق في خادم OAuth 2.0 من Google. توضّح الخطوات التالية كيفية إنشاء بيانات اعتماد لمشروعك. ويمكن لتطبيقاتك بعد ذلك استخدام بيانات الاعتماد للوصول إلى واجهات برمجة التطبيقات التي فعّلتها لهذا المشروع.

  1. Go to the Credentials page.
  2. انقر على إنشاء بيانات اعتماد > معرِّف عميل OAuth.
  3. اختَر نوع تطبيق تطبيق الويب.
  4. أكمل النموذج. إنّ التطبيقات التي تستخدم JavaScript لتقديم طلبات Google API المصرّح بها يجب أن تحدّد مصادر JavaScript المسموح بها. تحدّد المصادر النطاقات التي يمكن لتطبيقك إرسال طلبات منها إلى خادم OAuth 2.0. يجب أن تتقيّد هذه المصادر بقواعد التحقّق من Google.

تحديد نطاقات الوصول

تتيح النطاقات لتطبيقك طلب الوصول إلى الموارد التي يحتاج إليها فقط مع السماح للمستخدمين بالتحكم في مستوى الوصول الذي يمنحونه إلى تطبيقك. وبالتالي، قد تكون هناك علاقة عكسية بين عدد النطاقات المطلوبة واحتمالية الحصول على موافقة المستخدم.

قبل البدء في تنفيذ تفويض OAuth 2.0، ننصحك بتحديد النطاقات التي سيحتاج تطبيقك إلى إذن للوصول إليها.

يحتوي مستند نطاقات واجهة برمجة تطبيقات OAuth 2.0 على قائمة كاملة بالنطاقات التي قد تستخدمها للوصول إلى Google APIs.

الحصول على رموز الدخول عبر OAuth 2.0

توضّح الخطوات التالية كيفية تفاعل تطبيقك مع خادم OAuth 2.0 من Google للحصول على موافقة المستخدم على تنفيذ طلب البيانات من واجهة برمجة التطبيقات نيابةً عن المستخدم. يجب أن يحصل تطبيقك على تلك الموافقة حتى يتمكّن من تنفيذ طلب Google API الذي يتطلب تفويض المستخدم.

الخطوة 1: إعادة التوجيه إلى خادم OAuth 2.0 من Google

لطلب إذن الوصول إلى بيانات مستخدم، أعِد توجيه المستخدم إلى خادم OAuth 2.0 على Google.

نقاط نهاية OAuth 2.0

يمكنك إنشاء عنوان URL لطلب الوصول من نقطة نهاية OAuth 2.0 من Google على https://accounts.google.com/o/oauth2/v2/auth. يمكن الوصول إلى نقطة النهاية هذه من خلال HTTPS، ويتم رفض اتصالات HTTP العادية.

يتيح خادم التفويض في Google المعلَمات التالية لسلسلة طلب البحث لتطبيقات خادم الويب:

المَعلمات
client_id مطلوب

معرِّف العميل لتطبيقك. يمكنك العثور على هذه القيمة في API Console Credentials page.

redirect_uri مطلوب

تحدِّد هذه السياسة المواضع التي يُعيد فيها خادم واجهة برمجة التطبيقات توجيه المستخدم بعد أن يُكمل عملية التفويض. يجب أن تتطابق القيمة بشكل تام مع أحد معرِّفات الموارد المنتظمة (URI) المُعتمَدة لإعادة التوجيه لبرنامج OAuth 2.0، والتي تم ضبطها في API Console Credentials pageلعميلك. إذا لم تتطابق هذه القيمة مع معرّف الموارد المنتظم (URI) المصرّح به لإعادة التوجيه للسمة client_id المقدَّمة، ستظهر لك رسالة الخطأ redirect_uri_mismatch.

يجب أن يتطابق المخطط http أو https والحالة والشرطة المائلة اللاحقة ('/').

response_type مطلوب

ويجب أن تضبط تطبيقات JavaScript قيمة المَعلمة على token. توجّه هذه القيمة خادم التفويض في Google إلى عرض رمز الدخول كزوج name=value في معرّف الجزء من معرّف الموارد المنتظم (URI) (#) الذي تتم إعادة توجيه المستخدم إليه بعد إكمال عملية التفويض.

scope مطلوب

تمثّل هذه السمة قائمة النطاقات مع الفصل بينها بمسافات والتي تحدد الموارد التي يمكن لتطبيقك الوصول إليها نيابةً عن المستخدم. توضِّح هذه القيم شاشة طلب الموافقة التي يعرضها محرّك بحث Google للمستخدم.

تمكّن النطاقات تطبيقك من طلب الوصول إلى الموارد التي يحتاج إليها فقط مع تمكين المستخدمين أيضًا من التحكم في مقدار الوصول الذي يمنحونه لتطبيقك. وبالتالي، هناك علاقة عكسية بين عدد النطاقات المطلوبة واحتمالية الحصول على موافقة المستخدم.

ننصح بأن يطلب تطبيقك الوصول إلى نطاقات التفويض في السياق كلما أمكن ذلك. إنّ طلب الوصول إلى بيانات المستخدمين في السياق المناسب من خلال التفويض الإضافي يساعد المستخدمين على معرفة سبب احتياج التطبيق إلى إذن الوصول الذي يطلبه بسهولة.

state سمة مقترَحة

يحدِّد هذا الإعداد أي قيمة سلسلة يستخدمها تطبيقك للحفاظ على الحالة بين طلب التفويض واستجابة خادم التفويض. يعرض الخادم القيمة الدقيقة التي ترسلها كزوج name=value في معرّف جزء عنوان URL (#) من redirect_uri بعد موافقة المستخدم على طلب الوصول إلى تطبيقك أو رفضه.

يمكنك استخدام هذه المَعلمة لعدّة أغراض، مثل توجيه المستخدم إلى المورد الصحيح في تطبيقك، وإرسال أرقام تعريفية، والحدّ من حالات تزوير الطلبات من مواقع إلكترونية متعددة. بما أنّه يمكن تخمين redirect_uri، يمكن أن يزيد استخدام القيمة state من ضمانك بأنّ الاتصال الوارد ناتج عن طلب المصادقة. في حال إنشاء سلسلة عشوائية أو ترميز تجزئة ملف تعريف ارتباط أو قيمة أخرى تسجِّل حالة العميل، يمكنك التحقّق من الاستجابة للتأكد أيضًا من أنّ الطلب والاستجابة قد صدرا من المتصفّح نفسه، ما يوفّر الحماية ضد هجمات مثل تزييف الطلبات من مواقع إلكترونية متعددة. يمكنك الاطّلاع على مستندات ربط OpenID للحصول على مثال حول كيفية إنشاء رمز state مميز وتأكيده.

include_granted_scopes اختياريّ

تعمل هذه السياسة على تفعيل التطبيقات من استخدام التفويض المتزايد لطلب الوصول إلى نطاقات إضافية في السياق. في حال ضبط قيمة هذه المَعلمة على true ومنح طلب التفويض، سيغطي رمز الدخول الجديد أيضًا أي نطاقات سبق للمستخدِم أن منحها إذن الوصول إلى التطبيق. راجِع قسم التفويض الإضافي للاطّلاع على أمثلة.

login_hint اختياريّ

إذا كان تطبيقك يعرف المستخدم الذي يحاول المصادقة، يمكنه استخدام هذه المعلَمة لتقديم تلميح إلى خادم المصادقة في Google. ويستخدم الخادم التلميح لتبسيط عملية تسجيل الدخول، إما عن طريق ملء حقل البريد الإلكتروني مسبقًا في نموذج تسجيل الدخول أو عن طريق اختيار جلسة تسجيل الدخول المتعدد المناسبة.

اضبط قيمة المَعلمة على عنوان بريد إلكتروني أو معرّف sub، وهو ما يعادل رقم تعريف Google للمستخدم.

prompt اختياريّ

قائمة بالمطالبات التي يتم الفصل بينها بمسافات وحساسة لحالة الأحرف، لتقديم طلب تقديم المستخدم. إذا لم تحدّد هذه المعلَمة، سيُطلب من المستخدم فقط في المرة الأولى التي يطلب فيها مشروعك الإذن بالوصول. راجِع طلب إعادة الموافقة للاطّلاع على مزيد من المعلومات.

القيم المتاحة هي:

none لا تعرض أي شاشات مصادقة أو موافقة. ويجب عدم تحديدها باستخدام قيم أخرى.
consent طلب الموافقة من المستخدم
select_account مطالبة المستخدم باختيار حساب.

نموذج لإعادة التوجيه إلى خادم التفويض في Google

في ما يلي مثال على عنوان URL، مع فواصل الأسطر والمسافات لسهولة القراءة.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

بعد إنشاء عنوان URL للطلب، أعِد توجيه المستخدم إليه.

نموذج رمز JavaScript

يوضّح مقتطف JavaScript التالي كيفية بدء تدفق التفويض في JavaScript بدون استخدام مكتبة برامج Google APIs للغة JavaScript. بما أنّ نقطة نهاية OAuth 2.0 هذه لا تتوافق مع مشاركة الموارد المتعدّدة المصادر (CORS)، ينشئ المقتطف نموذجًا يفتح الطلب الخاص بنقطة النهاية هذه.

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

الخطوة 2: تطلب Google من المستخدم الموافقة

في هذه الخطوة، يقرّر المستخدم ما إذا كان سيمنح تطبيقك إذن الوصول المطلوب. في هذه المرحلة، تعرض Google نافذة موافقة تعرض اسم تطبيقك وخدمات Google API التي تطلب إذنًا للوصول إليها باستخدام بيانات اعتماد تفويض المستخدم وملخّصًا بنطاقات الوصول التي سيتم منحها. بعد ذلك، يستطيع المستخدم الموافقة على منح إذن الوصول إلى نطاق واحد أو أكثر من النطاقات التي يطلبها طلبك أو رفض الطلب.

ولا يحتاج تطبيقك إلى اتخاذ أي إجراء في هذه المرحلة، لأنّه ينتظر استجابة من خادم OAuth 2.0 من Google بشأن ما إذا كان قد تم منح أي إذن وصول أم لا. يتم شرح هذه الاستجابة في الخطوة التالية.

الأخطاء

قد تعرض الطلبات المُرسَلة إلى نقطة نهاية تفويض OAuth 2.0 من Google رسائل خطأ تظهر للمستخدمين بدلاً من مسارات المصادقة والترخيص المتوقّعة. في ما يلي رموز الأخطاء الشائعة والحلول المقترَحة.

admin_policy_enforced

لم يتمكّن حساب Google من تفويض نطاق واحد أو أكثر تم طلبه بسبب سياسات مشرف Google Workspace. يُرجى الاطّلاع على مقالة مساعدة مشرف Google Workspace التحكّم في اختيار تطبيقات الجهات الخارجية والتطبيقات الداخلية التي يمكنها الوصول إلى بيانات Google Workspace للتعرُّف على المزيد من المعلومات عن كيفية حظر المشرف للوصول إلى جميع النطاقات أو النطاقات الحساسة والمحدودة، إلى أن يتم منح الإذن بالوصول صراحةً إلى معرِّف عميل OAuth.

disallowed_useragent

يتم عرض نقطة نهاية التفويض داخل وكيل مستخدم مضمَّن لا تسمح به سياسات OAuth 2.0 في Google.

Android

قد تظهر رسالة الخطأ هذه لمطوّري تطبيقات Android عند فتح طلبات التفويض في android.webkit.WebView. وبدلاً من ذلك، على المطوّرين استخدام مكتبات Android، مثل تسجيل الدخول بحساب Google على أجهزة Android أو AppAuth لأجهزة Android من OpenID Foundation.

قد يظهر هذا الخطأ لمطوّري البرامج على الويب عندما يفتح أحد تطبيقات Android رابط ويب عامًا في وكيل مستخدم مضمّن وينتقل المستخدم إلى نقطة نهاية تفويض OAuth 2.0 من Google من موقعك الإلكتروني. ويجب أن يسمح مطوّرو البرامج بفتح الروابط العامة في معالِج الروابط التلقائي لنظام التشغيل، والذي يتضمّن كلاً من معالِجات روابط تطبيقات Android أو تطبيق المتصفّح التلقائي. ويمكن أيضًا استخدام مكتبة علامات التبويب المخصّصة لأجهزة Android.

iOS

قد يظهر هذا الخطأ لمطوّري تطبيقات iOS وmacOS عند فتح طلبات التفويض في WKWebView. وبدلاً من ذلك، على المطوّرين استخدام مكتبات iOS، مثل Google Sign-In لنظام التشغيل iOS أو AppAuth لأجهزة iOS من OpenID Foundation.

قد يظهر هذا الخطأ لمطوّري البرامج على الويب عندما يفتح أحد تطبيقات iOS أو macOS رابط ويب عامًا في وكيل مستخدم مضمّن وينتقل المستخدم إلى نقطة نهاية تفويض OAuth 2.0 من Google من موقعك الإلكتروني. يجب أن يسمح مطوّرو البرامج بفتح الروابط العامة في معالج الروابط التلقائي لنظام التشغيل، والذي يتضمّن كلاً من معالِجات الروابط العامة أو تطبيق المتصفّح التلقائي. وتُعد مكتبة SFSafariViewController خيارًا متوافقًا أيضًا.

org_internal

يمثّل معرّف عميل OAuth في الطلب جزءًا من مشروع يحدّ من الوصول إلى حسابات Google في مؤسسة Google Cloud معيّنة. لمزيد من المعلومات حول خيار الضبط هذا، يُرجى الاطّلاع على قسم نوع المستخدم في مقالة المساعدة حول إعداد شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth.

invalid_client

المصدر الذي تم تقديم الطلب منه غير مصرح به لهذا العميل. يمكنك الاطّلاع على origin_mismatch.

invalid_grant

عند استخدام تفويض إضافي، ربما انتهت صلاحية الرمز المميّز أو تم إبطاله. عليك المصادقة على المستخدم مرة أخرى وطلب موافقته على الحصول على رموز مميزة جديدة. إذا استمر ظهور هذا الخطأ، تأكَّد من ضبط التطبيق بشكل صحيح ومن أنك تستخدم الرموز المميّزة والمَعلمات الصحيحة في طلبك. وفي حال عدم تنفيذ ذلك، ربما تم حذف حساب المستخدم أو إيقافه.

origin_mismatch

إنّ مخطط و/أو نطاق و/أو منفذ JavaScript الذي أنشأ طلب التفويض قد لا يتطابق مع معرِّف موارد منتظم (URI) لمصدر JavaScript معتمد تم تسجيله في معرِّف عميل OAuth. راجِع مصادر JavaScript المسموح بها في Google API Console Credentials page.

redirect_uri_mismatch

لا يتطابق redirect_uri الذي تم تمريره في طلب التفويض مع معرّف موارد منتظم (URI) مُعتمَد لإعادة التوجيه لمعرِّف عميل OAuth. راجِع معرّفات الموارد المنتظمة (URI) المعتمَدة لإعادة التوجيه في Google API Console Credentials page.

إنّ مخطط و/أو نطاق و/أو منفذ JavaScript الذي أنشأ طلب التفويض قد لا يتطابق مع معرِّف موارد منتظم (URI) لمصدر JavaScript معتمد تم تسجيله في معرِّف عميل OAuth. راجِع مصادر JavaScript المسموح بها في Google API Console Credentials page.

قد تشير المَعلمة redirect_uri إلى مسار بروتوكول OAuth خارج النطاق (OOB) الذي تم إيقافه ولم يعد متاحًا. يُرجى الرجوع إلى دليل نقل البيانات لتعديل عملية الدمج.

invalid_request

حدث خطأ في الطلب الذي قدّمته. قد يرجع ذلك إلى عدة أسباب:

  • لم يتم تنسيق الطلب بشكلٍ صحيح
  • لم تتوفر المَعلمات المطلوبة في الطلب.
  • يستخدم الطلب طريقة تفويض غير معتمدة من Google. التحقّق من أن عملية دمج OAuth تستخدم طريقة دمج مقترَحة

الخطوة 3: التعامل مع استجابة خادم OAuth 2.0

نقاط نهاية OAuth 2.0

يرسل خادم OAuth 2.0 استجابة إلى redirect_uri المحددة في طلب رمز الدخول.

إذا وافق المستخدم على الطلب، فستحتوي الاستجابة على رمز دخول. إذا لم يوافق المستخدم على الطلب، سيحتوي الرد على رسالة خطأ. يتم عرض رمز الدخول أو رسالة الخطأ في جزء علامة التجزئة من معرّف الموارد المنتظم (URI) لإعادة التوجيه، كما هو موضّح أدناه:

  • استجابة رمز الدخول:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    بالإضافة إلى المَعلمة access_token، تحتوي سلسلة الجزء أيضًا على المَعلمة token_type التي يتم ضبطها دائمًا على Bearer والمَعلمة expires_in التي تحدّد مدة صلاحية الرمز المميّز بالثواني. إذا تم تحديد المَعلمة state في طلب رمز الدخول، يتم أيضًا تضمين قيمتها في الاستجابة.

  • الردّ على رسالة الخطأ:
    https://oauth2.example.com/callback#error=access_denied

نموذج استجابة خادم OAuth 2.0

يمكنك اختبار هذا الإجراء بالنقر على نموذج عنوان URL التالي، والذي يطلب الإذن بالقراءة فقط لعرض البيانات الوصفية للملفات في Google Drive:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

بعد إكمال مسار OAuth 2.0، ستتم إعادة توجيهك إلى http://localhost/oauth2callback. سيؤدي عنوان URL هذا إلى عرض الخطأ 404 NOT FOUND ما لم يكن جهازك المحلي يعرض ملفًا على هذا العنوان. تقدم الخطوة التالية مزيدًا من التفاصيل حول المعلومات التي يتم عرضها في معرّف الموارد المنتظم (URI) عندما تتم إعادة توجيه المستخدم إلى تطبيقك.

استدعاء Google APIs

نقاط نهاية OAuth 2.0

بعد أن يحصل تطبيقك على رمز دخول، يمكنك استخدام الرمز المميّز لإجراء طلبات بيانات من Google API نيابةً عن حساب مستخدم معيّن، وذلك إذا تم منح نطاقات الوصول التي تطلبها واجهة برمجة التطبيقات. ولإجراء ذلك، عليك تضمين رمز الدخول المميز في طلب متعلّق بواجهة برمجة التطبيقات عن طريق تضمين مَعلمة طلب البحث access_token أو قيمة Bearer لعنوان HTTP يتضمّن Authorization. ويفضَّل استخدام عنوان HTTP كلما أمكن ذلك، لأن سلاسل طلبات البحث غالبًا ما تكون مرئية في سجلات الخادم. في معظم الحالات، يمكنك استخدام مكتبة برامج لإعداد اتصالاتك في Google APIs (على سبيل المثال، عند طلب واجهة برمجة التطبيقات Drive Files API).

ويمكنك تجربة جميع واجهات برمجة تطبيقات Google وعرض نطاقاتها في ملعب OAuth 2.0.

أمثلة على HTTP GET

قد يبدو طلب نقطة نهاية drive.files (واجهة برمجة تطبيقات ملفات Drive) باستخدام عنوان HTTP Authorization: Bearer على النحو التالي. لاحظ أنك تحتاج إلى تحديد رمز الدخول الخاص بك:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

في ما يلي طلب بواجهة برمجة التطبيقات نفسها للمستخدم الذي تمت مصادقته باستخدام معلَمة سلسلة طلب البحث access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

أمثلة على curl

يمكنك اختبار هذه الأوامر باستخدام تطبيق سطر الأوامر curl. في ما يلي مثال يستخدم خيار عنوان HTTP (الخيار المفضّل):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

أو بدلاً من ذلك، خيار معلمة سلسلة طلب البحث:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

نموذج رمز JavaScript

يوضّح مقتطف الرمز أدناه كيفية استخدام مشاركة الموارد المتعدّدة المصادر (CORS) لإرسال طلب إلى واجهة برمجة تطبيقات Google. لا يستخدم هذا المثال مكتبة برامج Google APIs للغة JavaScript. وحتى إذا لم تكن تستخدم مكتبة البرامج، من المرجّح أن يساعدك دليل دعم سياسة مشاركة الموارد المتعدّدة المصادر (CORS) المتوفّر في مستندات تلك المكتبة على فهم هذه الطلبات بشكل أفضل.

في مقتطف الرمز هذا، يمثّل المتغيّر access_token الرمز المميّز الذي حصلت عليه لتقديم طلبات البيانات من واجهة برمجة التطبيقات نيابةً عن المستخدم المفوَّض. يوضّح المثال الكامل كيفية تخزين هذا الرمز المميّز في مساحة التخزين المحلية للمتصفّح واسترداده عند تقديم طلب من واجهة برمجة التطبيقات.

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

مثال كامل

نقاط نهاية OAuth 2.0

يعرض نموذج الرمز هذا كيفية إكمال مسار OAuth 2.0 في JavaScript بدون استخدام مكتبة برامج Google APIs للغة JavaScript. الرمز الخاص بصفحة HTML تعرض زرًا لتجربة طلب البيانات من واجهة برمجة التطبيقات. إذا نقرت على الزر، سيتحقّق الرمز مما إذا كانت الصفحة قد خزّنت رمز دخول مميّزًا لواجهة برمجة التطبيقات في مساحة التخزين المحلية على المتصفّح. وفي هذه الحالة، يتم تنفيذ طلب البيانات من واجهة برمجة التطبيقات. وبخلاف ذلك، يؤدّي ذلك إلى بدء مسار OAuth 2.0.

بالنسبة إلى مسار OAuth 2.0، تتبع الصفحة الخطوات التالية:

  1. يتم توجيه المستخدم إلى خادم OAuth 2.0 في Google، والذي يطلب الوصول إلى نطاق https://www.googleapis.com/auth/drive.metadata.readonly.
  2. بعد منح (أو رفض) إذن الوصول إلى نطاق مطلوب واحد أو أكثر، تتم إعادة توجيه المستخدم إلى الصفحة الأصلية، والتي تحلّل رمز الدخول من سلسلة معرّف الجزء.
  3. تستخدم الصفحة رمز الدخول لتقديم نموذج طلب من واجهة برمجة التطبيقات.

    يستدعي طلب البيانات من واجهة برمجة التطبيقات طريقة about.get الخاصة بـ Drive API لاسترداد معلومات حول حساب Google Drive للمستخدم المفوَّض.

  4. إذا تم تنفيذ الطلب بنجاح، يتم تسجيل استجابة واجهة برمجة التطبيقات في وحدة تحكُّم تصحيح الأخطاء الخاصة بالمتصفِّح.

يمكنك إبطال إمكانية الوصول إلى التطبيق من خلال صفحة الأذونات في حسابك على Google. سيتم إدراج التطبيق على أنه إصدار تجريبي من OAuth 2.0 لمستندات Google API.

لتشغيل هذا الرمز على الجهاز، يجب ضبط قيم للمتغيّرَين YOUR_CLIENT_ID وYOUR_REDIRECT_URI التي تتطابق مع بيانات اعتماد التفويض. يجب ضبط المتغيّر YOUR_REDIRECT_URI على عنوان URL نفسه الذي يتم عرض الصفحة عليه. يجب أن تتطابق القيمة تمامًا مع أحد معرِّفات الموارد المنتظمة (URI) المعتمَدة لإعادة التوجيه لعميل OAuth 2.0 الذي تم ضبطه في API Console Credentials page. إذا لم تتطابق هذه القيمة مع عنوان URL مصرّح به، ستظهر لك رسالة الخطأ redirect_uri_mismatch. يجب أن يكون مشروعك قد فعّل واجهة برمجة التطبيقات المناسبة لهذا الطلب.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

قواعد التحقّق من مصدر JavaScript

يطبِّق محرّك بحث Google قواعد التحقّق التالية على مصادر JavaScript لمساعدة المطوّرين في الحفاظ على أمان تطبيقاتهم. يجب أن تتقيّد مصادر JavaScript بهذه القواعد. راجِع القسم 3 من RFC 3986 للتعرّف على تعريف النطاق والمضيف والمخطط، كما هو موضّح أدناه.

قواعد التحقّق من الصحة
المخطط

يجب أن تستخدم مصادر JavaScript مخطّط HTTPS، وليس بروتوكول HTTP العادي. يتم إعفاء معرّفات الموارد المنتظمة (URI) للمضيف المحلي (بما في ذلك معرّفات الموارد المنتظمة (URI) لعناوين IP للمضيف المحلي) من هذه القاعدة.

المضيف

لا يمكن للمضيفين أن يكونوا عناوين IP أولية. يتم استثناء عناوين IP للمضيف المحلي من هذه القاعدة.

النطاق
  • يجب أن تنتمي نطاقات المستوى الأعلى (TLD) للمضيف (نطاقات المستوى الأعلى) إلى قائمة اللاحقات العلنية.
  • لا يمكن أن تكون نطاقات المضيف “googleusercontent.com”.
  • لا يمكن أن تحتوي مصادر JavaScript على نطاقات تقصير عناوين URL (مثل goo.gl) ما لم يكن التطبيق يملك النطاق.
  • معلومات المستخدم

    لا يمكن أن تحتوي أصول JavaScript على المكوّن الفرعي userinfo.

    المسار

    لا يمكن أن تحتوي أصول JavaScript على مكوّن المسار.

    طلب بحث

    لا يمكن أن تحتوي أصول JavaScript على مكوّن طلب البحث.

    جزء

    لا يمكن أن تحتوي أصول JavaScript على مكوّن الجزء.

    الأحرف لا يمكن أن تحتوي مصادر JavaScript على أحرف معيّنة من بينها:
    • أحرف البدل ('*')
    • أحرف ASCII غير قابلة للطباعة
    • ترميزات النسبة المئوية غير الصالحة (أي ترميز للنسبة المئوية لا يتّبع نموذج ترميز عناوين URL لعلامة النسبة المئوية متبوعة برقمين سداسي عشري)
    • أحرف فارغة (حرف فارغ مرمّز، مثل %00، %C0%80)

    التفويض التزايدي

    في بروتوكول OAuth 2.0، يطلب تطبيقك الإذن للوصول إلى الموارد التي يتم تحديدها حسب النطاقات. ويعتبر طلب الحصول على إذن للموارد عندما تحتاج إليها من بين أفضل الممارسات لتجربة المستخدم. ولتفعيل هذه الممارسة، يتيح خادم التفويض في Google التفويض التزايدي. تتيح لك هذه الميزة طلب النطاقات على النحو المطلوب، وفي حال منح المستخدم إذنًا للنطاق الجديد، تُرجع رمز التفويض الذي يمكن استبداله برمز مميز يحتوي على جميع النطاقات التي منحها المستخدم للمشروع.

    على سبيل المثال، قد يحتاج التطبيق الذي يتيح للمستخدمين أخذ عينات من المقاطع الموسيقية وإنشاء تشكيلات إلى موارد قليلة جدًا عند تسجيل الدخول، وربما أكثر من اسم الشخص الذي يسجّل الدخول. في المقابل، يتطلب حفظ مزيج مكتمل الوصول إلى Google Drive الخاص به. يجد معظم المستخدمين أنه من الطبيعي أن يطلبوا منهم الوصول إلى Google Drive فقط في الوقت الذي يحتاج فيه التطبيق إلى ذلك.

    في هذه الحالة، في وقت تسجيل الدخول، قد يطلب التطبيق النطاقَين openid وprofile لإجراء تسجيل الدخول الأساسي، ثم يطلب بعد ذلك نطاق https://www.googleapis.com/auth/drive.file في وقت تقديم الطلب الأول لحفظ تشكيلة.

    تنطبق القواعد التالية على رمز الدخول الذي تم الحصول عليه من تفويض تزايدي:

    • يمكن استخدام الرمز المميّز للوصول إلى الموارد المقابلة لأي من النطاقات التي تم تضمينها في عملية التفويض الجديدة والمجمّعة.
    • عند استخدام الرمز المميز لإعادة التحميل للتفويض المجمّع للحصول على رمز دخول، يمثّل رمز الدخول الإذن المجمّع ويمكن استخدامه في أي من قيم scope المضمّنة في الاستجابة.
    • ويشمل التفويض المجمّع جميع النطاقات التي منحها المستخدم لمشروع واجهة برمجة التطبيقات حتى إذا كان قد تم طلب المنح من عملاء مختلفين. على سبيل المثال، إذا منح المستخدم إمكانية الوصول إلى نطاق باستخدام برنامج متوافق مع أجهزة الكمبيوتر المكتبي في تطبيق معيَّن، ثم منحه نطاقًا آخر للتطبيق نفسه من خلال برنامج متوافق مع الأجهزة الجوّالة، سيتضمّن التفويض المجمّع كلا النطاقين.
    • في حال إبطال رمز مميّز يمثّل تفويضًا مجمّعًا، يتم في الوقت نفسه إبطال إمكانية الوصول إلى جميع نطاقات هذا الإذن نيابةً عن المستخدم المرتبط.

    تعرض نماذج التعليمات البرمجية أدناه كيفية إضافة نطاقات إلى رمز دخول حالي. ويتيح هذا الأسلوب لتطبيقك تجنُّب إدارة عدة رموز دخول.

    نقاط نهاية OAuth 2.0

    لإضافة نطاقات إلى رمز دخول حالي، يمكنك تضمين المَعلمة include_granted_scopes في طلب دخولك إلى خادم OAuth 2.0 من Google.

    ويوضّح مقتطف الرمز التالي كيفية إجراء ذلك. يفترض المقتطف أنك خزّنت النطاقات التي يكون رمز الدخول صالحًا لها في مساحة التخزين المحلية للمتصفح. (يخزِّن رمز المثال الكامل قائمة بالنطاقات التي يكون رمز الدخول صالحًا لها من خلال ضبط السمة oauth2-test-params.scope في مساحة التخزين المحلية للمتصفّح).

    يقارن المقتطف بين النطاقات التي يكون رمز الدخول صالحًا لها بالنطاق الذي تريد استخدامه لطلب بحث محدّد. وإذا كان رمز الدخول لا يغطي هذا النطاق، سيبدأ مسار OAuth 2.0. في هذه الحالة، تكون الدالة oauth2SignIn هي نفسها التي تم توفيرها في الخطوة 2 (والتي تم توفيرها لاحقًا في المثال الكامل).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    إبطال رمز مميّز

    في بعض الحالات، قد يرغب المستخدم في إبطال حق الوصول الممنوح لأحد التطبيقات. ويمكن للمستخدم إبطال إذن الوصول من خلال الانتقال إلى إعدادات الحساب. للحصول على مزيد من المعلومات، يمكنك الاطّلاع على قسم إزالة إمكانية وصول الموقع الإلكتروني أو التطبيق إلى المواقع الإلكترونية والتطبيقات التابعة لجهات خارجية والتي يمكنها الوصول إلى حسابك للحصول على مزيد من المعلومات.

    من الممكن أيضًا أن يلغي التطبيق إمكانية الوصول الممنوح له بشكل آلي. تُعدّ الإبطال الآلي أمرًا مهمًا في الحالات التي يلغي فيها المستخدم اشتراكه أو يزيله أو تغيَّرت موارد واجهة برمجة التطبيقات التي يتطلبها التطبيق بشكل كبير. بمعنى آخر، يمكن أن يتضمّن جزء من عملية الإزالة طلب البيانات من واجهة برمجة التطبيقات لضمان إزالة الأذونات التي تم منحها سابقًا للتطبيق.

    نقاط نهاية OAuth 2.0

    لإبطال رمز مميّز آليًا، يقدّم تطبيقك طلبًا إلى https://oauth2.googleapis.com/revoke ويتضمّن الرمز المميّز كمَعلمة:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    يمكن أن يكون الرمز المميّز رمز دخول أو رمز إعادة تحميل. إذا كان الرمز المميّز عبارة عن رمز دخول وله رمز إعادة تحميل مطابق، سيتم أيضًا إبطال الرمز المميّز لإعادة التحميل.

    إذا تمت معالجة الإبطال بنجاح، يكون رمز حالة HTTP للاستجابة هو 200. بالنسبة إلى حالات الخطأ، يتم عرض رمز حالة HTTP 400 مع رمز خطأ.

    يوضّح مقتطف JavaScript التالي كيفية إبطال رمز مميّز في JavaScript بدون استخدام مكتبة برامج Google APIs للغة JavaScript. بما أنّ نقطة نهاية OAuth 2.0 من Google لإلغاء الرموز المميّزة لا تتوافق مع مشاركة الموارد المتعدّدة المصادر (CORS)، ينشئ الرمز نموذجًا ويرسله إلى نقطة النهاية بدلاً من استخدام طريقة XMLHttpRequest() لنشر الطلب.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }