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 تفعيل واجهات برمجة التطبيقات هذه في API Console.

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

  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 يتطلّب تفويض المستخدم.

الخطوة 1: ضبط كائن العميل

إذا كنت تستخدم مكتبة برامج Google APIs للغة JavaScript لمعالجة تدفق OAuth 2.0، تتمثل الخطوة الأولى في ضبط الكائنين gapi.auth2 وgapi.client. وتتيح هذه العناصر للتطبيق الحصول على إذن المستخدم وتقديم طلبات من خلال واجهة برمجة التطبيقات.

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

مكتبة برامج JavaScript

تبسّط مكتبة عميل JavaScript جوانب عديدة من عملية التفويض:

  1. تنشئ هذه الطريقة عنوان URL لإعادة التوجيه لخادم مصادقة Google وتوفّر طريقة لتوجيه المستخدم إلى عنوان URL هذا.
  2. فهو يعالج عملية إعادة التوجيه من هذا الخادم إلى تطبيقك.
  3. تتحقق هذه الخدمة من رمز الدخول الذي يعرضه خادم المصادقة.
  4. وهو يخزّن رمز الدخول الذي يرسله خادم التفويض إلى تطبيقك ويسترده عند إجراء طلبات البيانات من واجهة برمجة التطبيقات في تطبيقك بعد ذلك.

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

يحدّد المكالمة إلى gapi.client.init الحقول التالية:

  • تحدّد القيم apiKey وclientId بيانات اعتماد تفويض التطبيق. كما هو موضّح في القسم إنشاء بيانات اعتماد التفويض، يمكن الحصول على هذه القيم في API Console. وتجدر الإشارة إلى أنّ السمة clientId مطلوبة إذا كان طلبك يقدّم طلبات من واجهة برمجة التطبيقات. ويمكن للتطبيقات التي تقدم طلبات غير مصرّح بها فقط تحديد مفتاح واجهة برمجة التطبيقات.
  • يحدّد الحقل scope قائمة بنطاقات الوصول مفصولة بمسافات تتوافق مع الموارد التي يمكن لتطبيقك الوصول إليها نيابةً عن المستخدم. وتحدّد هذه القيم شاشة الموافقة التي يعرضها محرّك البحث Google للمستخدم.

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

  • يحدِّد الحقل discoveryDocs قائمة بمستندات Discovery API التي يستخدمها تطبيقك. ويوضّح مستند "اقتراحات" مساحة واجهة برمجة التطبيقات، بما في ذلك مخططات الموارد، وتستخدم مكتبة برامج JavaScript هذه المعلومات لإنشاء طرق يمكن للتطبيقات استخدامها. في هذا المثال، يسترد الرمز مستند الاكتشاف للإصدار 3 من واجهة برمجة تطبيقات Google Drive.

بعد اكتمال الاستدعاء gapi.client.init، يحدد الرمز المتغيّر GoogleAuth لتحديد كائن Google Auth. وأخيرًا، يحدّد الرمز مستمعًا يستدعي دالة عندما تتغيّر حالة تسجيل دخول المستخدم. (هذه الدالة غير معرَّفة في المقتطف).

var GoogleAuth; // Google Auth object.
function initClient() {
  gapi.client.init({
      'apiKey': 'YOUR_API_KEY',
      'clientId': 'YOUR_CLIENT_ID',
      'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
      'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']
  }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);
  });
}

نقاط نهاية OAuth 2.0

إذا كنت تصل مباشرةً إلى نقاط نهاية OAuth 2.0، يمكنك المتابعة إلى الخطوة التالية.

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

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

مكتبة برامج JavaScript

يمكنك استدعاء طريقة GoogleAuth.signIn() لتوجيه المستخدم إلى خادم تفويض Google.

GoogleAuth.signIn();

عمليًا، قد يحدّد تطبيقك قيمة منطقية لتحديد ما إذا كان سيتم استدعاء الطريقة signIn() قبل محاولة إجراء طلب بيانات من واجهة برمجة التطبيقات.

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

  • العنصر GoogleAuth المشار إليه في الرمز هو نفسه للمتغيّر العام المحدَّد في مقتطف الرمز في الخطوة 1.

  • الدالة updateSigninStatus عبارة عن مستمع يستمع إلى التغييرات التي تطرأ على حالة تفويض المستخدم. وتم أيضًا تحديد دور المستمع في مقتطف الرمز في الخطوة 1:
    GoogleAuth.isSignedIn.listen(updateSigninStatus);
  • يحدّد المقتطف متغيرَين عموميَين إضافيَين:

    • isAuthorized هو متغيّر منطقي يشير إلى ما إذا كان المستخدم مسجّلاً الدخول أم لا. ويمكن تحديد هذه القيمة عند تحميل التطبيق وتحديثه إذا سجّل المستخدم دخوله أو الخروج منه.

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

    • currentApiRequest هي عبارة عن كائن يخزّن تفاصيل حول آخر طلب قدّمته واجهة برمجة التطبيقات. يتم ضبط قيمة العنصر عند استدعاء التطبيق للدالة sendAuthorizedApiRequest.

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

var isAuthorized;
var currentApiRequest;

/**
 * Store the request details. Then check to determine whether the user
 * has authorized the application.
 *   - If the user has granted access, make the API request.
 *   - If the user has not granted access, initiate the sign-in flow.
 */
function sendAuthorizedApiRequest(requestDetails) {
  currentApiRequest = requestDetails;
  if (isAuthorized) {
    // Make API request
    // gapi.client.request(requestDetails)

    // Reset currentApiRequest variable.
    currentApiRequest = {};
  } else {
    GoogleAuth.signIn();
  }
}

/**
 * Listener called when user completes auth flow. If the currentApiRequest
 * variable is set, then the user was prompted to authorize the application
 * before the request executed. In that case, proceed with that API request.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    isAuthorized = true;
    if (currentApiRequest) {
      sendAuthorizedApiRequest(currentApiRequest);
    }
  } else {
    isAuthorized = false;
  }
}

نقاط نهاية 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 Connect للاطّلاع على مثال عن كيفية إنشاء رمز مميّز 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();
}

الخطوة 3: تطلب 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 for Android في مؤسسة OpenID.

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

iOS

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

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

org_internal

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

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.

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

مكتبة برامج JavaScript

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

نقاط نهاية 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

مكتبة برامج JavaScript

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

توفّر مكتبة العملاء طريقتَين لاستدعاء طرق واجهة برمجة التطبيقات. إذا حمّلت مستندًا أثناء التصفّح، ستحدّد واجهة برمجة التطبيقات الدوال الخاصة بطريقة معيّنة. يمكنك أيضًا استخدام الدالة gapi.client.request لطلب طريقة من واجهة برمجة التطبيقات. يعرض المقتطفان التاليان هذه الخيارات لطريقة about.get واجهة برمجة التطبيقات في Drive.

// Example 1: Use method-specific function
var request = gapi.client.drive.about.get({'fields': 'user'});

// Execute the API request.
request.execute(function(response) {
  console.log(response);
});


// Example 2: Use gapi.client.request(args) function
var request = gapi.client.request({
  'method': 'GET',
  'path': '/drive/v3/about',
  'params': {'fields': 'user'}
});
// Execute the API request.
request.execute(function(response) {
  console.log(response);
});

نقاط نهاية OAuth 2.0

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

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

أمثلة على 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 API. لا يستخدم هذا المثال مكتبة عميل 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);

مثال كامل

مكتبة برامج JavaScript

إصدار تجريبي للرمز النموذجي

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

لاحظ أن هذا التطبيق يطلب الوصول إلى نطاق https://www.googleapis.com/auth/drive.metadata.readonly. ويُطلب الإذن بالوصول فقط لتوضيح كيفية بدء مسار OAuth 2.0 في تطبيق JavaScript. لا يقدّم هذا التطبيق أي طلبات من خلال واجهة برمجة التطبيقات.

نموذج رمز JavaScript

كما هو موضّح أعلاه، يهدف نموذج الرمز هذا إلى صفحة (تطبيق) تحمِّل "مكتبة عميل Google APIs" للغة JavaScript وتبدأ تدفق OAuth 2.0. وتعرض الصفحة أيًا مما يلي:

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

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

<script>
  var GoogleAuth;
  var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  function handleClientLoad() {
    // Load the API's client and auth2 modules.
    // Call the initClient function after the modules load.
    gapi.load('client:auth2', initClient);
  }

  function initClient() {
    // In practice, your app can retrieve one or more discovery documents.
    var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

    // Initialize the gapi.client object, which app uses to make API requests.
    // Get API key and client ID from API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

      // Call handleAuthClick function when user clicks on
      //      "Sign In/Authorize" button.
      $('#sign-in-or-out-button').click(function() {
        handleAuthClick();
      });
      $('#revoke-access-button').click(function() {
        revokeAccess();
      });
    });
  }

  function handleAuthClick() {
    if (GoogleAuth.isSignedIn.get()) {
      // User is authorized and has clicked "Sign out" button.
      GoogleAuth.signOut();
    } else {
      // User is not signed in. Start Google auth flow.
      GoogleAuth.signIn();
    }
  }

  function revokeAccess() {
    GoogleAuth.disconnect();
  }

  function setSigninStatus() {
    var user = GoogleAuth.currentUser.get();
    var isAuthorized = user.hasGrantedScopes(SCOPE);
    if (isAuthorized) {
      $('#sign-in-or-out-button').html('Sign out');
      $('#revoke-access-button').css('display', 'inline-block');
      $('#auth-status').html('You are currently signed in and have granted ' +
          'access to this app.');
    } else {
      $('#sign-in-or-out-button').html('Sign In/Authorize');
      $('#revoke-access-button').css('display', 'none');
      $('#auth-status').html('You have not authorized this app or you are ' +
          'signed out.');
    }
  }

  function updateSigninStatus() {
    setSigninStatus();
  }
</script>

<button id="sign-in-or-out-button"
        style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
        style="display: none; margin-left: 25px">Revoke access</button>

<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

نقاط نهاية 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 لاسترداد معلومات حول حساب المستخدم المعتمد في 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. وإذا لم تتطابق هذه القيمة مع أي معرّف موارد منتظم (URI) معتمَد، سيظهر لك الخطأ 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 3986 للتعرّف على تعريف النطاق والمضيف والمخطط المذكور أدناه.

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

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

المضيف

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

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

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

    المسار

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

    طلب بحث

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

    الجزء

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

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

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

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

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

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

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

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

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

    مكتبة برامج JavaScript

    لإضافة نطاقات إلى رمز دخول حالي، يمكنك استدعاء طريقة GoogleUser.grant(options). يحدّد العنصر options النطاقات الإضافية التي تريد منح حق الوصول إليها.

    // Space-separated list of additional scope(s) you are requesting access to.
    // This code adds read-only access to the user's calendars via the Calendar API.
    var NEW_SCOPES = 'https://www.googleapis.com/auth/calendar.readonly';
    
    // Retrieve the GoogleUser object for the current user.
    var GoogleUser = GoogleAuth.currentUser.get();
    GoogleUser.grant({'scope': NEW_SCOPES});

    نقاط نهاية 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.
    }

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

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

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

    مكتبة برامج JavaScript

    لإبطال رمز مميّز آليًا، يمكنك استدعاء ما يلي: GoogleAuth.disconnect():

    GoogleAuth.disconnect();

    نقاط نهاية 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();
    }