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 API إلى تفعيل واجهات برمجة التطبيقات هذه في 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 على بيانات اعتماد التفويض التي تحدد التطبيق في خادم OAuth 2.0 التابع لـ Google. توضّح الخطوات التالية كيفية إنشاء بيانات الاعتماد لمشروعك. ويمكن للتطبيقات بعد ذلك استخدام بيانات الاعتماد للوصول إلى واجهات برمجة التطبيقات التي فعّلتها لذلك المشروع.

  1. Go to the Credentials page.
  2. انقر على إنشاء بيانات الاعتماد &gt؛ معرِّف عميل 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 Discovery التي يستخدمها تطبيقك. ويصف مستند "اقتراحات" سطح واجهة برمجة التطبيقات، بما في ذلك مخططات المورد، وتستخدم مكتبة عميل JavaScript هذه المعلومات لإنشاء طرق يمكن للتطبيقات استخدامها. في هذا المثال، يسترد الرمز مستند الاكتشاف للإصدار 3 من واجهة برمجة تطبيقات Google Drive.

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

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.0s على Google.

مكتبة عملاء JavaScript

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

GoogleAuth.signIn();

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

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

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

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

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

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

    • currentApiRequest هي عنصر يخزّن تفاصيل حول آخر طلب بيانات من واجهة برمجة التطبيقات حاول المستخدم تنفيذه. يتم ضبط قيمة object&s عندما يستدعي التطبيق الدالة 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، الذي هيأته في البرنامج الخاص بك's 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 أو OpenID Foundation وAppAuth لنظام التشغيل Android بدلاً من ذلك.

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

iOS

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

قد يواجه مطوّرو البرامج على الويب هذا الخطأ عندما يفتح تطبيق 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 API

مكتبة عملاء JavaScript

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

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

// 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 نيابةً عن حساب مستخدم معيّن إذا تم منح نطاقات الوصول المطلوبة من خلال واجهة برمجة التطبيقات. ولإجراء ذلك، يمكنك تضمين رمز الدخول في طلب الوصول إلى واجهة برمجة التطبيقات من خلال تضمين معلمة طلب البحث access_token أو قيمة عنوان HTTP Authorization Bearer. وننصحك باستخدام عنوان HTTP، لأن سلاسل طلبات البحث غالبًا ما تكون مرئية في سجلات الخادم. وفي معظم الحالات، يمكنك استخدام مكتبة برامج لإعداد طلباتك على Google APIs (مثل استدعاء واجهة برمجة تطبيقات الملفات في Drive).

ويمكنك تجربة جميع واجهات برمجة تطبيقات 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 API. ولا يستخدم هذا المثال مكتبة برامج Google APIs لجافا سكريبت. وحتى إذا لم تكن تستخدم مكتبة العملاء، سيساعدك دليل دعم سياسة مشاركة الموارد متعددة المصادر (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 Demo في مستندات 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. يتم إدراج التطبيق باسم إصدار OAuth 2.0 التجريبي لمحرّر مستندات Google API.

<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 لجافا سكريبت. الرمز مخصّص لصفحة 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 بهذه القواعد. يمكنك الاطّلاع على القسم RFC 3986 للتعرّف على تعريف النطاق والمضيف والمخطّط المذكور أدناه.

قواعد التحقّق
النظام

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

المضيف

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

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

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

    مكتبة عملاء 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&#29.4 لإلغاء الرموز المميّزة لا تتوافق مع مشاركة الموارد المشتركة المنشأ (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();
    }