استخدام OAuth 2.0 لتطبيقات خادم الويب

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

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

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

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

مكتبات العملاء

تستخدم الأمثلة الخاصة باللغات في هذه الصفحة مكتبات عميل Google API لتنفيذ تفويض OAuth 2.0. لتشغيل نماذج الرموز، يجب أولاً تثبيت مكتبة البرامج بلغتك.

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

تتوفر مكتبات عميل واجهة برمجة تطبيقات 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. املأ النموذج وانقر على إنشاء. إنّ التطبيقات التي تستخدم لغات وأُطر عمل، مثل PHP وJava وPython وRuby و .NET يجب أن تحدّد معرّفات موارد منتظمة (URI) مسموح بها لإعادة التوجيه. معرّفات الموارد المنتظمة (URI) لإعادة التوجيه هي نقاط النهاية التي يمكن لخادم OAuth 2.0 إرسال الردود إليها. ويجب أن تتقيّد نقاط النهاية هذه بقواعد التحقق من Google.

    لأغراض الاختبار، يمكنك تحديد معرّفات الموارد المنتظمة التي تشير إلى الجهاز المحلي، مثل http://localhost:8080. مع أخذ ذلك في الاعتبار، يُرجى ملاحظة أنّ جميع الأمثلة في هذا المستند تستخدم http://localhost:8080 باعتباره معرّف الموارد المنتظم (URI) لإعادة التوجيه.

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

بعد إنشاء بيانات الاعتماد، نزِّل الملف client_secret.json من API Console. يمكنك تخزين الملف بأمان في موقع لا يمكن سوى لتطبيقك الوصول إليه.

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

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

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

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

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

المتطلبات الخاصة بكل لغة

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

PHP

لتشغيل نماذج التعليمات البرمجية PHP في هذا المستند، سوف تحتاج إلى:

  • الإصدار 5.6 من لغة PHP أو إصدار أحدث مع تثبيت واجهة سطر الأوامر (CLI) وإضافة JSON.
  • أداة إدارة التبعية Composer
  • مكتبة برامج Google APIs للغة PHP:

    composer require google/apiclient:^2.10

Python

لتشغيل نماذج التعليمات البرمجية Python في هذا المستند، سوف تحتاج إلى:

  • Python 2.6 أو أحدث
  • أداة إدارة الحزمة pip
  • مكتبة برامج Google APIs للغة Python:
    pip install --upgrade google-api-python-client
  • google-auth وgoogle-auth-oauthlib وgoogle-auth-httplib2 لتفويض المستخدم.
    pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
  • إطار عمل تطبيق الويب Flask Python.
    pip install --upgrade flask
  • مكتبة HTTP requests
    pip install --upgrade requests

Ruby

لتشغيل نماذج التعليمات البرمجية Ruby في هذا المستند، ستحتاج إلى:

  • Ruby 2.6 أو إصدار أحدث
  • مكتبة مصادقة Google للغة Ruby:

    gem install googleauth
  • إطار عمل تطبيق الويب Sinatra Ruby

    gem install sinatra

Node.js

لتشغيل نماذج التعليمات البرمجية لـ Node.js في هذا المستند، ستحتاج إلى:

  • قناة الدعم الطويل الأمد (LTS) أو قناة الدعم الطويل الأمد (LTS) النشطة أو الإصدار الحالي من Node.js
  • عميل Node.js لواجهات Google APIs:

    npm install googleapis

HTTP/REST

لا تحتاج إلى تثبيت أي مكتبات لتتمكن من الاتصال بنقاط نهاية OAuth 2.0 مباشرةً.

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

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

وتلخّص القائمة التالية هذه الخطوات بسرعة:

  1. يحدد تطبيقك الأذونات التي يحتاجها.
  2. يُعيد تطبيقك توجيه المستخدم إلى Google مع قائمة الأذونات المطلوبة.
  3. يقرّر المستخدم ما إذا كان سيتم منح الأذونات لتطبيقك أم لا.
  4. يكتشف تطبيقك ما قرره المستخدم.
  5. إذا منح المستخدم الأذونات المطلوبة، يسترد تطبيقك الرموز المميّزة اللازمة لتقديم طلبات البيانات من واجهة برمجة التطبيقات نيابةً عن المستخدم.

الخطوة 1: ضبط مَعلمات التفويض

تتمثل خطوتك الأولى في إنشاء طلب التفويض. يضبط هذا الطلب المعلَمات التي تحدّد تطبيقك وتحدّد الأذونات التي سيُطلب من المستخدم منحها لتطبيقك.

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

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

PHP

ينشئ مقتطف الرمز أدناه كائن Google\Client() يحدد المعلَمات في طلب التفويض.

ويستخدم هذا الكائن معلومات من ملف client_secret.json لتحديد تطبيقك. (راجع إنشاء بيانات اعتماد التفويض للحصول على مزيد من المعلومات حول هذا الملف). يحدد الكائن أيضًا النطاقات التي يطلب تطبيقك إذنًا للوصول إليها وعنوان URL لنقطة نهاية المصادقة لتطبيقك، والتي ستتعامل مع الاستجابة من خادم OAuth 2.0 في Google. أخيرًا، يحدّد الرمز المَعلمتَين access_type وinclude_granted_scopes الاختياريتَين.

على سبيل المثال، يتطلب هذا الرمز إذنًا بالقراءة فقط بلا اتصال بالإنترنت إلى Google Drive للمستخدم:

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');
// Using "consent" will prompt the user for consent
$client->setPrompt('consent');
$client->setIncludeGrantedScopes(true);   // incremental auth

ويحدّد الطلب المعلومات التالية:

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

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

في لغة PHP، يمكنك استدعاء الدالة setAuthConfig لتحميل بيانات اعتماد التفويض من ملف client_secret.json.

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');
redirect_uri مطلوب

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

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

لضبط هذه القيمة في PHP، استدعِ الدالة setRedirectUri. وتجدُر الإشارة إلى أنّه يجب تحديد معرّف موارد منتظم (URI) صالح لإعادة التوجيه للسمة client_id المقدَّمة.

$client->setRedirectUri('https://oauth2.example.com/code');
scope مطلوب

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

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

لضبط هذه القيمة في PHP، استدعِ الدالة addScope:

$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

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

access_type سمة مقترَحة

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

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

لضبط هذه القيمة في PHP، استدعِ الدالة setAccessType:

$client->setAccessType('offline');
state سمة مقترَحة

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

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

لضبط هذه القيمة في PHP، استدعِ الدالة setState:

$client->setState($sample_passthrough_value);
include_granted_scopes اختياريّ

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

لضبط هذه القيمة في PHP، استدعِ الدالة setIncludeGrantedScopes:

$client->setIncludeGrantedScopes(true);
login_hint اختياريّ

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

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

لضبط هذه القيمة في PHP، استدعِ الدالة setLoginHint:

$client->setLoginHint('None');
prompt اختياريّ

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

لضبط هذه القيمة في PHP، استدعِ الدالة setPrompt:

$client->setPrompt('consent');

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

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

Python

يستخدم مقتطف الرمز التالي الوحدة google-auth-oauthlib.flow لإنشاء طلب التفويض.

ينشئ الرمز كائن Flow يحدّد تطبيقك باستخدام معلومات من ملف client_secret.json الذي نزّلته بعد إنشاء بيانات اعتماد التفويض. يحدّد ذلك الكائن أيضًا النطاقات التي يطلب تطبيقك إذنًا للوصول إليها وعنوان URL لنقطة نهاية المصادقة لتطبيقك، والتي ستتعامل مع الاستجابة الواردة من خادم OAuth 2.0 في Google. أخيرًا، يحدّد الرمز المَعلمتَين access_type وinclude_granted_scopes الاختياريتَين.

على سبيل المثال، يتطلب هذا الرمز إذنًا بالقراءة فقط بلا اتصال بالإنترنت إلى Google Drive للمستخدم:

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Use the client_secret.json file to identify the application requesting
# authorization. The client ID (from that file) and access scopes are required.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])

# Indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
flow.redirect_uri = 'https://www.example.com/oauth2callback'

# Generate URL for request to Google's OAuth 2.0 server.
# Use kwargs to set optional request parameters.
authorization_url, state = flow.authorization_url(
    # Enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type='offline',
    # Enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true')

ويحدّد الطلب المعلومات التالية:

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

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

في لغة بايثون، يمكنك استدعاء الطريقة from_client_secrets_file لاسترداد معرِّف العميل من ملف client_secret.json. (يمكنك أيضًا استخدام الطريقة from_client_config، التي تضبط إعدادات العميل كما ظهرت في الأصل في ملف أسرار العميل ولكنّها لا تصل إلى الملف نفسه).

flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])
redirect_uri مطلوب

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

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

لضبط هذه القيمة في Python، اضبط السمة redirect_uri للكائن flow:

flow.redirect_uri = 'https://oauth2.example.com/code'
scope مطلوب

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

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

في بايثون، استخدِم الطريقة نفسها التي تستخدمها لضبط client_id لتحديد قائمة النطاقات.

flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])

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

access_type سمة مقترَحة

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

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

في بايثون، اضبط المعلَمة access_type من خلال تحديد access_type كوسيطة كلمة رئيسية عند استدعاء الطريقة flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
state سمة مقترَحة

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

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

في بايثون، اضبط المعلَمة state من خلال تحديد state كوسيطة كلمة رئيسية عند استدعاء الطريقة flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    state=sample_passthrough_value,
    include_granted_scopes='true')
include_granted_scopes اختياريّ

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

في بايثون، اضبط المعلَمة include_granted_scopes من خلال تحديد include_granted_scopes كوسيطة كلمة رئيسية عند استدعاء الطريقة flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
login_hint اختياريّ

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

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

في بايثون، اضبط المعلَمة login_hint من خلال تحديد login_hint كوسيطة كلمة رئيسية عند استدعاء الطريقة flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    login_hint='None',
    include_granted_scopes='true')
prompt اختياريّ

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

في بايثون، اضبط المعلَمة prompt من خلال تحديد prompt كوسيطة كلمة رئيسية عند استدعاء الطريقة flow.authorization_url:

authorization_url, state = flow.authorization_url(
      access_type='offline',
      prompt='consent',
      include_granted_scopes='true')

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

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

Ruby

استخدِم ملف client_secrets.json الذي أنشأته لضبط كائن العميل في تطبيقك. عند إعداد كائن عميل، يمكنك تحديد النطاقات التي يحتاج تطبيقك إلى الوصول إليها، بالإضافة إلى عنوان URL لنقطة نهاية المصادقة في تطبيقك، والتي ستتعامل مع الاستجابة الواردة من خادم OAuth 2.0.

على سبيل المثال، يتطلب هذا الرمز إذنًا بالقراءة فقط بلا اتصال بالإنترنت إلى Google Drive للمستخدم:

require 'google/apis/drive_v3'
require "googleauth"
require 'googleauth/stores/redis_token_store'

client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')
scope = 'https://www.googleapis.com/auth/drive.metadata.readonly'
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')

Your application uses the client object to perform OAuth 2.0 operations, such as generating authorization request URLs and applying access tokens to HTTP requests.

Node.js

The code snippet below creates a google.auth.OAuth2 object, which defines the parameters in the authorization request.

That object uses information from your client_secret.json file to identify your application. To ask for permissions from a user to retrieve an access token, you redirect them to a consent page. To create a consent page URL:

const {google} = require('googleapis');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
 * from the client_secret.json file. To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a url that asks permissions for the Drive activity scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true
});

ملاحظة مهمة: لا يتم عرض refresh_token إلا على التفويض الأول فقط. يمكنك الاطّلاع على المزيد من التفاصيل هنا.

HTTP/REST

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

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

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

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

redirect_uri مطلوب

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

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

response_type مطلوب

تحدِّد هذه السياسة ما إذا كانت نقطة نهاية Google OAuth 2.0 تعرض رمز تفويض.

اضبط قيمة المَعلمة على code لتطبيقات خادم الويب.

scope مطلوب

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

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

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

access_type سمة مقترَحة

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

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

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

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

PHP

  1. يمكنك إنشاء عنوان URL لطلب الوصول من خادم OAuth 2.0 من Google:
    $auth_url = $client->createAuthUrl();
  2. إعادة توجيه المستخدم إلى $auth_url:
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

يوضّح هذا المثال كيفية إعادة توجيه المستخدم إلى عنوان URL للتفويض باستخدام إطار عمل تطبيق الويب Flask:

return flask.redirect(authorization_url)

Ruby

  1. يمكنك إنشاء عنوان URL لطلب الوصول من خادم OAuth 2.0 من Google:
    auth_uri = authorizer.get_authorization_url(login_hint: user_id, request: request)
  2. إعادة توجيه المستخدم إلى auth_uri.

Node.js

  1. استخدم طريقة عنوان URL الذي تم إنشاؤه authorizationUrl من الخطوة 1 generateAuthUrl لطلب الوصول من خادم OAuth 2.0 في Google.
  2. إعادة توجيه المستخدم إلى authorizationUrl.
    res.writeHead(301, { "Location": authorizationUrl });

HTTP/REST

Sample redirect to Google's authorization server

An example URL is shown below, with line breaks and spaces for readability.

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

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

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

الخطوة 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 Foundation.

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

iOS

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

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

org_internal

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

invalid_client

سر عميل OAuth غير صحيح. راجِع إعدادات عميل OAuth، بما في ذلك معرِّف العميل والسر المستخدَم لهذا الطلب.

invalid_grant

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

redirect_uri_mismatch

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

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

invalid_request

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

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

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

يستجيب خادم OAuth 2.0 لطلب الوصول إلى تطبيقك باستخدام عنوان URL المحدَّد في الطلب.

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

استجابة خطأ:

https://oauth2.example.com/auth?error=access_denied

استجابة رمز التفويض:

https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7

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

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

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

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

الخطوة 5: تبديل رمز التفويض لرموز إعادة التحميل ورموز الدخول

بعد أن يتلقّى خادم الويب رمز التفويض، يمكنه استبدال رمز التفويض برمز دخول.

PHP

لاستبدال رمز التفويض برمز دخول، استخدِم طريقة authenticate:

$client->authenticate($_GET['code']);

يمكنك استرداد رمز الدخول باستخدام طريقة getAccessToken:

$access_token = $client->getAccessToken();

Python

في صفحة معاودة الاتصال، استخدِم مكتبة google-auth للتحقّق من استجابة خادم التفويض. بعد ذلك، استخدِم الإجراء flow.fetch_token لاستبدال رمز التفويض في هذه الاستجابة برمز دخول:

state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'],
    state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)

# Store the credentials in the session.
# ACTION ITEM for developers:
#     Store user's access and refresh tokens in your data store if
#     incorporating this code into your real app.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'token_uri': credentials.token_uri,
    'client_id': credentials.client_id,
    'client_secret': credentials.client_secret,
    'scopes': credentials.scopes}

Ruby

في صفحة معاودة الاتصال، استخدِم مكتبة googleauth للتحقّق من استجابة خادم التفويض. استخدِم الطريقة authorizer.handle_auth_callback_deferred لحفظ رمز التفويض وإعادة التوجيه إلى عنوان URL الذي طلب التفويض في الأصل. ويؤدي ذلك إلى تأجيل عملية تبادل الرمز عن طريق التخزين المؤقت للنتائج في جلسة المستخدم.

  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url

Node.js

لاستبدال رمز التفويض برمز دخول، استخدِم طريقة getToken:

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
if (req.url.startsWith('/oauth2callback')) {
  // Handle the OAuth 2.0 server response
  let q = url.parse(req.url, true).query;

  // Get access and refresh tokens (if access_type is offline)
  let { tokens } = await oauth2Client.getToken(q.code);
  oauth2Client.setCredentials(tokens);
}

HTTP/REST

لاستبدال رمز التفويض برمز دخول، يمكنك استدعاء نقطة النهاية https://oauth2.googleapis.com/token وضبط المَعلمات التالية:

الحقول
client_id معرِّف العميل الذي تم الحصول عليه من API Console Credentials page.
client_secret سر العميل الذي تم الحصول عليه من API Console Credentials page.
code رمز التفويض الذي تم عرضه من الطلب الأولي
grant_type كما هو موضّح في مواصفات OAuth 2.0، يجب ضبط قيمة هذا الحقل على authorization_code.
redirect_uri أحد معرّفات الموارد المنتظمة (URI) لإعادة التوجيه والتي تم إدراجها لمشروعك في API Console Credentials page لمعرّف client_id المحدد.

يعرض المقتطف التالي نموذجًا لطلب:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

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

يحتوي الرد على الحقول التالية:

الحقول
access_token الرمز المميّز الذي يرسله تطبيقك لتفويض طلب من واجهة Google API
expires_in المدة المتبقية لرمز الدخول بالثواني.
refresh_token رمز مميز يمكنك استخدامه للحصول على رمز دخول جديد. وتكون الرموز المميّزة لإعادة التحميل صالحة إلى أن يُبطِل المستخدم إذن الوصول. مرة أخرى، لا يتوفّر هذا الحقل في هذه الاستجابة إلّا إذا ضبطت المَعلمة access_type على offline في الطلب الأوّلي إلى خادم التفويض في Google.
scope نطاقات الوصول التي تم منحها في access_token، ويتم التعبير عنها في شكل قائمة من السلاسل الحساسة لحالة الأحرف والمحددة بمسافات.
token_type نوع الرمز المميّز الذي تم عرضه. في الوقت الحالي، يتم ضبط قيمة هذا الحقل دائمًا على Bearer.

يعرض المقتطف التالي نموذجًا للإجابة:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

الأخطاء

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

invalid_grant

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

استدعاء واجهات Google APIs

PHP

استخدم رمز الدخول للاتصال بواجهات Google APIs من خلال إكمال الخطوات التالية:

  1. إذا كنت بحاجة إلى تطبيق رمز دخول على عنصر Google\Client جديد، على سبيل المثال، إذا كنت قد خزّنت رمز الدخول في جلسة مستخدم، يمكنك استخدام طريقة setAccessToken:
    $client->setAccessToken($access_token);
  2. أنشئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها. يمكنك إنشاء كائن خدمة من خلال توفير كائن Google\Client مصرّح به إلى الدالة الإنشائية لواجهة برمجة التطبيقات التي تريد طلبها. على سبيل المثال، لطلب بيانات Drive API:
    $drive = new Google\Service\Drive($client);
  3. يمكنك تقديم طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام الواجهة التي يوفّرها كائن الخدمة. على سبيل المثال، لإدراج الملفات في حساب Google Drive للمستخدم الذي تمت مصادقته:
    $files = $drive->files->listFiles(array())->getItems();

Python

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

  1. أنشئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها. يمكنك إنشاء عنصر خدمة من خلال استدعاء الإجراء build في مكتبة googleapiclient.discovery مع اسم واجهة برمجة التطبيقات وإصدارها وبيانات اعتماد المستخدم، على سبيل المثال، لطلب الإصدار 3 من Drive API:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. يمكنك تقديم طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام الواجهة التي يوفّرها كائن الخدمة. على سبيل المثال، لإدراج الملفات في حساب Google Drive للمستخدم الذي تمت مصادقته:
    files = drive.files().list().execute()

Ruby

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

  1. أنشئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها. على سبيل المثال، لطلب الإصدار 3 من Drive API:
    drive = Google::Apis::DriveV3::DriveService.new
  2. اضبط بيانات الاعتماد في الخدمة:
    drive.authorization = credentials
  3. يمكنك إرسال طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام الواجهة التي يوفّرها كائن الخدمة. على سبيل المثال، لإدراج الملفات في حساب Google Drive للمستخدم الذي تمت مصادقته:
    files = drive.list_files

بدلاً من ذلك، يمكن منح التفويض على أساس كل طريقة من خلال توفير المَعلمة options إلى إحدى الطرق:

files = drive.list_files(options: { authorization: credentials })

Node.js

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

const { google } = require('googleapis');

// Example of using Google Drive API to list filenames in user's Drive.
const drive = google.drive('v3');
drive.files.list({
  auth: oauth2Client,
  pageSize: 10,
  fields: 'nextPageToken, files(id, name)',
}, (err1, res1) => {
  if (err1) return console.log('The API returned an error: ' + err1);
  const files = res1.data.files;
  if (files.length) {
    console.log('Files:');
    files.map((file) => {
      console.log(`${file.name} (${file.id})`);
    });
  } else {
    console.log('No files found.');
  }
});

HTTP/REST

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

مثال كامل

يطبع المثال التالي قائمة ملفات بتنسيق JSON في حساب المستخدم على Google Drive بعد أن يجري المستخدم عملية مصادقة ويوافق على وصول التطبيق إلى البيانات الوصفية في Drive للمستخدم.

PHP

لتشغيل هذا المثال:

  1. في API Console، أضِف عنوان URL للجهاز المحلي إلى قائمة عناوين URL لإعادة التوجيه. على سبيل المثال، أضِف http://localhost:8080.
  2. إنشاء دليل جديد وإجراء تغييرات عليه مثلاً:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. ثبِّت مكتبة برامج Google API للغة PHP باستخدام Composer:
    composer require google/apiclient:^2.10
    .
  4. أنشئ الملفين index.php وoauth2callback.php بالمحتوى أدناه.
  5. شغِّل المثال مع خادم ويب تم إعداده لعرض لغة PHP. إذا كنت تستخدم الإصدار 5.6 من لغة PHP أو إصدارًا أحدث، يمكنك استخدام خادم الويب التجريبي المُضمَّن في PHP:
    php -S localhost:8080 ~/php-oauth2-example

index.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfig('client_secrets.json');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $client->setAccessToken($_SESSION['access_token']);
  $drive = new Google\Service\Drive($client);
  $files = $drive->files->listFiles(array())->getItems();
  echo json_encode($files);
} else {
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

oauth2callback.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfigFile('client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

if (! isset($_GET['code'])) {
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
  $client->authenticate($_GET['code']);
  $_SESSION['access_token'] = $client->getAccessToken();
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

Python

يستخدم هذا المثال إطار عمل Flask. ويشغّل تطبيق ويب في http://localhost:8080 يتيح لك اختبار مسار OAuth 2.0. إذا انتقلت إلى عنوان URL هذا، من المفترض أن ترى أربعة روابط:

  • اختبار طلب البيانات من واجهة برمجة التطبيقات: يشير هذا الرابط إلى صفحة تحاول تنفيذ نموذج طلب من واجهة برمجة التطبيقات. وعند الضرورة، يبدأ تدفق التفويض. في حال نجاح هذا الإجراء، ستعرض الصفحة استجابة واجهة برمجة التطبيقات.
  • اختبار مسار المصادقة مباشرةً: يشير هذا الرابط إلى صفحة تحاول إرسال المستخدم من خلال مسار التفويض. يطلب التطبيق إذنًا لإرسال طلبات البيانات من واجهة برمجة التطبيقات المصرّح بها نيابةً عن المستخدم.
  • إبطال بيانات الاعتماد الحالية: يشير هذا الرابط إلى صفحة تُبطِل الأذونات التي سبق أن منحها المستخدم للتطبيق.
  • محو بيانات اعتماد جلسة Flask: يؤدي هذا الرابط إلى محو بيانات اعتماد التفويض المخزّنة في جلسة Flask. يتيح لك ذلك معرفة ما سيحدث إذا حاول مستخدم سبق له منح الإذن لتطبيقك تنفيذ طلب بيانات من واجهة برمجة التطبيقات في جلسة جديدة. يتيح لك أيضًا الاطّلاع على استجابة واجهة برمجة التطبيقات التي سيحصل عليها تطبيقك إذا أبطل المستخدم الأذونات التي تم منحها لتطبيقك، واستمر تطبيقك في محاولة منح الإذن بطلب باستخدام رمز دخول تم إبطاله.
# -*- coding: utf-8 -*-

import os
import flask
import requests

import google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery

# This variable specifies the name of a file that contains the OAuth 2.0
# information for this application, including its client_id and client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
API_SERVICE_NAME = 'drive'
API_VERSION = 'v2'

app = flask.Flask(__name__)
# Note: A secret key is included in the sample so that it works.
# If you use this code in your application, replace this with a truly secret
# key. See https://flask.palletsprojects.com/quickstart/#sessions.
app.secret_key = 'REPLACE ME - this value is here as a placeholder.'


@app.route('/')
def index():
  return print_index_table()


@app.route('/test')
def test_api_request():
  if 'credentials' not in flask.session:
    return flask.redirect('authorize')

  # Load credentials from the session.
  credentials = google.oauth2.credentials.Credentials(
      **flask.session['credentials'])

  drive = googleapiclient.discovery.build(
      API_SERVICE_NAME, API_VERSION, credentials=credentials)

  files = drive.files().list().execute()

  # Save credentials back to session in case access token was refreshed.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.jsonify(**files)


@app.route('/authorize')
def authorize():
  # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES)

  # The URI created here must exactly match one of the authorized redirect URIs
  # for the OAuth 2.0 client, which you configured in the API Console. If this
  # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
  # error.
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  authorization_url, state = flow.authorization_url(
      # Enable offline access so that you can refresh an access token without
      # re-prompting the user for permission. Recommended for web server apps.
      access_type='offline',
      # Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes='true')

  # Store the state so the callback can verify the auth server response.
  flask.session['state'] = state

  return flask.redirect(authorization_url)


@app.route('/oauth2callback')
def oauth2callback():
  # Specify the state when creating the flow in the callback so that it can
  # verified in the authorization server response.
  state = flask.session['state']

  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  # Use the authorization server's response to fetch the OAuth 2.0 tokens.
  authorization_response = flask.request.url
  flow.fetch_token(authorization_response=authorization_response)

  # Store credentials in the session.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  credentials = flow.credentials
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.redirect(flask.url_for('test_api_request'))


@app.route('/revoke')
def revoke():
  if 'credentials' not in flask.session:
    return ('You need to <a href="/authorize">authorize</a> before ' +
            'testing the code to revoke credentials.')

  credentials = google.oauth2.credentials.Credentials(
    **flask.session['credentials'])

  revoke = requests.post('https://oauth2.googleapis.com/revoke',
      params={'token': credentials.token},
      headers = {'content-type': 'application/x-www-form-urlencoded'})

  status_code = getattr(revoke, 'status_code')
  if status_code == 200:
    return('Credentials successfully revoked.' + print_index_table())
  else:
    return('An error occurred.' + print_index_table())


@app.route('/clear')
def clear_credentials():
  if 'credentials' in flask.session:
    del flask.session['credentials']
  return ('Credentials have been cleared.<br><br>' +
          print_index_table())


def credentials_to_dict(credentials):
  return {'token': credentials.token,
          'refresh_token': credentials.refresh_token,
          'token_uri': credentials.token_uri,
          'client_id': credentials.client_id,
          'client_secret': credentials.client_secret,
          'scopes': credentials.scopes}

def print_index_table():
  return ('<table>' +
          '<tr><td><a href="/test">Test an API request</a></td>' +
          '<td>Submit an API request and see a formatted JSON response. ' +
          '    Go through the authorization flow if there are no stored ' +
          '    credentials for the user.</td></tr>' +
          '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
          '<td>Go directly to the authorization flow. If there are stored ' +
          '    credentials, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' +
          '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
          '<td>Revoke the access token associated with the current user ' +
          '    session. After revoking credentials, if you go to the test ' +
          '    page, you should see an <code>invalid_grant</code> error.' +
          '</td></tr>' +
          '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
          '<td>Clear the access token currently stored in the user session. ' +
          '    After clearing the token, if you <a href="/test">test the ' +
          '    API request</a> again, you should go back to the auth flow.' +
          '</td></tr></table>')


if __name__ == '__main__':
  # When running locally, disable OAuthlib's HTTPs verification.
  # ACTION ITEM for developers:
  #     When running in production *do not* leave this option enabled.
  os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

  # Specify a hostname and port that are set as a valid redirect URI
  # for your API project in the Google API Console.
  app.run('localhost', 8080, debug=True)

Ruby

يستخدم هذا المثال إطار عمل Sinatra.

require 'google/apis/drive_v3'
require 'sinatra'
require 'googleauth'
require 'googleauth/stores/redis_token_store'

configure do
  enable :sessions

  set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')
  set :scope, Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY
  set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
  set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, '/oauth2callback')
end

get '/' do
  user_id = settings.client_id.id
  credentials = settings.authorizer.get_credentials(user_id, request)
  if credentials.nil?
    redirect settings.authorizer.get_authorization_url(login_hint: user_id, request: request)
  end
  drive = Google::Apis::DriveV3::DriveService.new
  files = drive.list_files(options: { authorization: credentials })
  "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
end

get '/oauth2callback' do
  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url
end

Node.js

لتشغيل هذا المثال:

  1. في API Console، أضِف عنوان URL للجهاز المحلي إلى قائمة عناوين URL لإعادة التوجيه. على سبيل المثال، أضِف http://localhost.
  2. تأكَّد من تثبيت قناة الدعم الطويل الأمد (LTS) أو قناة الدعم الطويل الأمد (LTS) أو الإصدار الحالي من Node.js.
  3. إنشاء دليل جديد وإجراء تغييرات عليه مثلاً:
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. Install the Google API Client Library for Node.js using npm:
    npm install googleapis
  5. يمكنك إنشاء الملفات main.js باستخدام المحتوى أدناه.
  6. شغِّل المثال:
    node .\main.js

main.js

const http = require('http');
const https = require('https');
const url = require('url');
const { google } = require('googleapis');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
 * To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a url that asks permissions for the Drive activity scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true
});

/* Global variable that stores user credential in this code example.
 * ACTION ITEM for developers:
 *   Store user's refresh token in your data store if
 *   incorporating this code into your real app.
 *   For more information on handling refresh tokens,
 *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
 */
let userCredential = null;

async function main() {
  const server = http.createServer(async function (req, res) {
    // Example on redirecting user to Google's OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }

    // Receive the callback from Google's OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) { // An error response e.g. error=access_denied
        console.log('Error:' + q.error);
      } else { // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        oauth2Client.setCredentials(tokens);

        /** Save credential to the global variable in case access token was refreshed.
          * ACTION ITEM: In a production app, you likely want to save the refresh token
          *              in a secure persistent database instead. */
        userCredential = tokens;

        // Example of using Google Drive API to list filenames in user's Drive.
        const drive = google.drive('v3');
        drive.files.list({
          auth: oauth2Client,
          pageSize: 10,
          fields: 'nextPageToken, files(id, name)',
        }, (err1, res1) => {
          if (err1) return console.log('The API returned an error: ' + err1);
          const files = res1.data.files;
          if (files.length) {
            console.log('Files:');
            files.map((file) => {
              console.log(`${file.name} (${file.id})`);
            });
          } else {
            console.log('No files found.');
          }
        });
      }
    }

    // Example on revoking a token
    if (req.url == '/revoke') {
      // Build the string for the POST request
      let postData = "token=" + userCredential.access_token;

      // Options for POST request to Google's OAuth 2.0 server to revoke a token
      let postOptions = {
        host: 'oauth2.googleapis.com',
        port: '443',
        path: '/revoke',
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': Buffer.byteLength(postData)
        }
      };

      // Set up the request
      const postReq = https.request(postOptions, function (res) {
        res.setEncoding('utf8');
        res.on('data', d => {
          console.log('Response: ' + d);
        });
      });

      postReq.on('error', error => {
        console.log(error)
      });

      // Post the request with data
      postReq.write(postData);
      postReq.end();
    }
    res.end();
  }).listen(80);
}
main().catch(console.error);

HTTP/REST

يستخدم مثال بايثون هذا إطار عمل Flask ومكتبة الطلبات لتوضيح تدفق OAuth 2.0 على الويب. نوصي باستخدام مكتبة برامج Google API للغة بايثون في هذا المسار. (يستخدم المثال في علامة التبويب Python مكتبة العميل.)

import json

import flask
import requests


app = flask.Flask(__name__)

CLIENT_ID = '123456789.apps.googleusercontent.com'
CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app
SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly'
REDIRECT_URI = 'http://example.com/oauth2callback'


@app.route('/')
def index():
  if 'credentials' not in flask.session:
    return flask.redirect(flask.url_for('oauth2callback'))
  credentials = json.loads(flask.session['credentials'])
  if credentials['expires_in'] <= 0:
    return flask.redirect(flask.url_for('oauth2callback'))
  else:
    headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
    req_uri = 'https://www.googleapis.com/drive/v2/files'
    r = requests.get(req_uri, headers=headers)
    return r.text


@app.route('/oauth2callback')
def oauth2callback():
  if 'code' not in flask.request.args:
    auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                '&client_id={}&redirect_uri={}&scope={}').format(CLIENT_ID, REDIRECT_URI, SCOPE)
    return flask.redirect(auth_uri)
  else:
    auth_code = flask.request.args.get('code')
    data = {'code': auth_code,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI,
            'grant_type': 'authorization_code'}
    r = requests.post('https://oauth2.googleapis.com/token', data=data)
    flask.session['credentials'] = r.text
    return flask.redirect(flask.url_for('index'))


if __name__ == '__main__':
  import uuid
  app.secret_key = str(uuid.uuid4())
  app.debug = False
  app.run()

قواعد التحقق من معرِّف الموارد المنتظم (URI) لإعادة التوجيه

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

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

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

المضيف

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

النطاق
  • يجب أن تنتمي نطاقات المستوى الأعلى للمضيف (نطاقات المستوى الأعلى) إلى قائمة اللاحقات العلنية.
  • لا يمكن أن تكون نطاقات المضيف “googleusercontent.com”.
  • لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على نطاقات تقصير عنوان URL (مثل goo.gl) ما لم يكن التطبيق يملك النطاق. بالإضافة إلى ذلك، إذا اختار تطبيق يمتلك نطاقًا أقصر إعادة التوجيه إلى ذلك النطاق، يجب أن يحتوي معرّف الموارد المنتظم (URI) لإعادة التوجيه هذا على “/google-callback/” في مساره أو أن ينتهي بالرمز “/google-callback”.
  • معلومات المستخدم

    لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على المكوِّن الفرعي لمعلومات المستخدم.

    المسار

    لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على مسح للمسار (يُعرف أيضًا باسم تراجع الدليل)، والذي يتم تمثيله بترميز “/..” أو “\..” أو ترميز عنوان URL الخاص بهما.

    طلب بحث

    لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على عمليات إعادة توجيه مفتوحة.

    جزء

    لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على مكون التجزئة.

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

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

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

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

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

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

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

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

    إنّ نماذج الرموز الخاصة بكل لغة في الخطوة الأولى: ضبط معلَمات التفويض ونموذج عنوان URL لإعادة التوجيه HTTP/REST في الخطوة 2: إعادة التوجيه إلى خادم OAuth 2.0 من Google تستخدم جميعها تفويضًا تزايديًا. تعرض نماذج الرموز أدناه أيضًا الرمز الذي تحتاج إلى إضافته لاستخدام التفويض التزايدي.

    PHP

    $client->setIncludeGrantedScopes(true);

    Python

    في بايثون، يمكنك ضبط وسيطة الكلمة الرئيسية include_granted_scopes على true للتأكد من أنّ طلب التفويض يتضمّن نطاقات تم منحها سابقًا. من المحتمل جدًا ألا تكون include_granted_scopes هي وسيطة الكلمة الرئيسية الوحيدة التي تضبطها، كما هو موضّح في المثال أدناه.

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    Ruby

    auth_client.update!(
      :additional_parameters => {"include_granted_scopes" => "true"}
    )

    Node.js

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });
    

    HTTP/REST

    GET https://accounts.google.com/o/oauth2/v2/auth?
      client_id=your_client_id&
      response_type=code&
      state=state_parameter_passthrough_value&
      scope=https%3A//www.googleapis.com/auth/drive.file&
      redirect_uri=https%3A//oauth2.example.com/code&
      prompt=consent&
      include_granted_scopes=true

    إعادة تحميل رمز الدخول (الوصول بلا إنترنت)

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

    • في حال استخدام مكتبة برامج Google API، يُعيد كائن العميل تحديث رمز الدخول حسب الحاجة ما دام يتم إعداد هذا العنصر للوصول بلا اتصال بالإنترنت.
    • إذا كنت لا تستخدم مكتبة برامج، عليك ضبط مَعلمة طلب البحث access_type HTTP على offline عند إعادة توجيه المستخدم إلى خادم OAuth 2.0 في Google. في هذه الحالة، يعرض خادم التفويض في Google الرمز المميز لإعادة التحميل عند استبدال رمز التفويض برمز دخول. وبعد ذلك، إذا انتهت صلاحية رمز الدخول (أو في أي وقت آخر)، يمكنك استخدام الرمز المميّز لإعادة التحميل للحصول على رمز دخول جديد.

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

    تحصل تطبيقات الويب من جهة الخادم والتطبيقات المثبَّتة والأجهزة على رموز التحديث أثناء عملية التفويض. فرموز إعادة التحميل لا تُستخدم عادةً في تطبيقات الويب من جهة العميل (JavaScript).

    PHP

    إذا كان تطبيقك يحتاج إلى الوصول بلا اتصال بالإنترنت إلى واجهة برمجة تطبيقات Google، اضبط نوع وصول عميل واجهة برمجة التطبيقات على offline:

    $client->setAccessType("offline");

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

    Python

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

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

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

    Ruby

    إذا كان تطبيقك يحتاج إلى الوصول بلا اتصال بالإنترنت إلى واجهة برمجة تطبيقات Google، اضبط نوع وصول عميل واجهة برمجة التطبيقات على offline:

    auth_client.update!(
      :additional_parameters => {"access_type" => "offline"}
    )

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

    Node.js

    إذا كان تطبيقك يحتاج إلى الوصول بلا اتصال بالإنترنت إلى واجهة برمجة تطبيقات Google، اضبط نوع وصول عميل واجهة برمجة التطبيقات على offline:

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });
    

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

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

    oauth2Client.on('tokens', (tokens) => {
      if (tokens.refresh_token) {
        // store the refresh_token in your secure persistent database
        console.log(tokens.refresh_token);
      }
      console.log(tokens.access_token);
    });

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

    لضبط refresh_token في وقت لاحق، يمكنك استخدام الطريقة setCredentials:

    oauth2Client.setCredentials({
      refresh_token: `STORED_REFRESH_TOKEN`
    });
    

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

    HTTP/REST

    لإعادة تحميل رمز الدخول، يرسل تطبيقك طلب HTTPS POST إلى خادم تفويض Google (https://oauth2.googleapis.com/token) يتضمّن المَعلمات التالية:

    الحقول
    client_id معرِّف العميل الذي تم الحصول عليه من API Console.
    client_secret سر العميل الذي تم الحصول عليه من API Console.
    grant_type كما المحدّدة في مواصفات OAuth 2.0، يجب ضبط قيمة هذا الحقل على refresh_token.
    refresh_token الرمز المميز لإعادة التحميل الذي يعرضه تبادل رمز التفويض.

    يعرض المقتطف التالي نموذجًا لطلب:

    POST /token HTTP/1.1
    Host: oauth2.googleapis.com
    Content-Type: application/x-www-form-urlencoded
    
    client_id=your_client_id&
    client_secret=your_client_secret&
    refresh_token=refresh_token&
    grant_type=refresh_token

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

    {
      "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
      "expires_in": 3920,
      "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
      "token_type": "Bearer"
    }

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

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

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

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

    PHP

    لإبطال رمز مميّز آليًا، يمكنك طلب الرمز البرمجي revokeToken():

    $client->revokeToken();

    Python

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

    requests.post('https://oauth2.googleapis.com/revoke',
        params={'token': credentials.token},
        headers = {'content-type': 'application/x-www-form-urlencoded'})

    Ruby

    لإبطال رمز مميّز آليًا، يمكنك إرسال طلب HTTP إلى نقطة النهاية oauth2.revoke:

    uri = URI('https://oauth2.googleapis.com/revoke')
    response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
    

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

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

    Node.js

    لإبطال رمز مميّز آليًا، يمكنك تقديم طلب HTTPS POST إلى نقطة نهاية /revoke:

    const https = require('https');
    
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;
    
    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };
    
    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });
    
    postReq.on('error', error => {
      console.log(error)
    });
    
    // Post the request with data
    postReq.write(postData);
    postReq.end();
    

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

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

    HTTP/REST

    لإبطال رمز مميّز آليًا، يرسل تطبيقك طلبًا إلى 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 مع رمز خطأ.