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

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

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

عند استخدام مكتبة عميل واجهة برمجة تطبيقات Google للتعامل مع تدفق 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 وجافا سكريبت وPython وRuby و .NET عناوين URI لإعادة التوجيه معتمدة. عناوين URL لإعادة التوجيه هي نقاط النهاية التي يمكن لخادم OAuth 2.0 إرسال استجابات إليها. ويجب أن تلتزم نقاط النهاية هذه بقواعد التحقّق من صحّة Google.

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

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

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

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

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

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

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

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

المتطلبات المتعلقة بكل لغة

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

لغة PHP

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

  • لغة PHP الإصدار 5.6 أو الأحدث مع تثبيت واجهة سطر الأوامر (CLI) وإضافة JSON.
  • أداة إدارة تبعية الملحّن.
  • مكتبة برامج 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.2.2 أو أحدث
  • مكتبة برامج Google APIs للغة Ruby:

    gem install google-api-client
  • إطار عمل تطبيق الويب 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 الذي يتطلب إذن المستخدم.

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

  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" ensures that your application always receives a refresh token.
// If you are not using offline access, you can omit this.
$client->setApprovalPrompt('consent');
$client->setIncludeGrantedScopes(true);   // incremental auth

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

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

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

في 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، يمكنك استدعاء الدالة setApprovalPrompt:

$client->setApprovalPrompt('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 مطلوب

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

في Python، يمكنك استدعاء طريقة 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 للمستخدم.

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

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

في Python، اضبط المَعلمة 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 وتأكيده.

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

في Python، اضبط المَعلمة 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 للمستخدم.

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

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

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

في Python، اضبط المَعلمة 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_v2'
require 'google/api_client/client_secrets'

client_secrets = Google::APIClient::ClientSecrets.load
auth_client = client_secrets.to_authorization
auth_client.update!(
  :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly',
  :redirect_uri => 'http://www.example.com/oauth2callback',
  :additional_parameters => {
    "access_type" => "offline",         # offline access
    "include_granted_scopes" => "true"  # incremental auth
  }
)

يستخدم تطبيقك كائن العميل لإجراء عمليات OAuth 2.0، مثل إنشاء عناوين URL لطلب التفويض وتطبيق رموز الدخول على طلبات HTTP.

Node.js

ينشئ مقتطف الرمز أدناه كائن google.auth.OAuth2، والذي يحدّد المعلّمات في طلب التفويض.

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

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

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 = auth_client.authorization_uri.to_s
  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 لأجهزة Android الخاصة بمؤسسة OpenID.

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

iOS

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

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

org_internal

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

invalid_client

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

invalid_grant

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

redirect_uri_mismatch

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

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

الخطوة 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: رمز تفويض Exchange للرموز المميزة للتحديث والوصول

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

لغة 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

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

auth_client.code = auth_code
auth_client.fetch_access_token!

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 أحد عناوين URL لإعادة التوجيه المُدرَجة لمشروعك في 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 من خلال إكمال الخطوات التالية:

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

لغة Python

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

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

Ruby

استخدِم الكائن auth_client لاستدعاء Google APIs من خلال إكمال الخطوات التالية:

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

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

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

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

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

أمثلة HTTP GET

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

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 require google/apiclient:^2.10
  4. أنشِئ الملفَين index.php وoauth2callback.php باستخدام المحتوى أدناه.
  5. شغِّل المثال مع خادم ويب تم إعداده لعرض PHP. إذا كنت تستخدم لغة PHP 5.6 أو إصدارًا أحدث، يمكنك استخدام خادم الويب المُدمج لاختبار PHP:
    php -S localhost:8080 ~/php-oauth2-example

.index

<?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_v2'
require 'google/api_client/client_secrets'
require 'json'
require 'sinatra'

enable :sessions
set :session_secret, 'setme'

get '/' do
  unless session.has_key?(:credentials)
    redirect to('/oauth2callback')
  end
  client_opts = JSON.parse(session[:credentials])
  auth_client = Signet::OAuth2::Client.new(client_opts)
  drive = Google::Apis::DriveV2::DriveService.new
  files = drive.list_files(options: { authorization: auth_client })
  "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
end

get '/oauth2callback' do
  client_secrets = Google::APIClient::ClientSecrets.load
  auth_client = client_secrets.to_authorization
  auth_client.update!(
    :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly',
    :redirect_uri => url('/oauth2callback'))
  if request['code'] == nil
    auth_uri = auth_client.authorization_uri.to_s
    redirect to(auth_uri)
  else
    auth_client.code = request['code']
    auth_client.fetch_access_token!
    auth_client.client_secret = nil
    session[:credentials] = auth_client.to_json
    redirect to('/')
  end
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

.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

يستخدم مثال Python هذا إطار عمل Flask ومكتبة الطلبات لعرض تدفق الويب OAuth 2.0. ننصح باستخدام مكتبة برامج "واجهة Google API" للغة Python في هذه العملية. (يستخدم المثال في علامة التبويب 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) لمساعدة مطوّري البرامج في الحفاظ على أمان تطبيقاتهم. يجب أن تلتزم عناوين URL لإعادة التوجيه بهذه القواعد. يُرجى الاطّلاع على القسم 3986 RFC 3 للحصول على تعريف النطاق والمضيف والمسار وطلب البحث والمخطط ومعلومات المستخدم المذكورة أدناه.

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

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

المضيف

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

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

    لا يمكن أن تحتوي عناوين URL لإعادة التوجيه على المكوّن الفرعي userinfo.

    المسار

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

    طلب بحث

    لا يمكن أن تحتوي عناوين URL لإعادة التوجيه على عمليات إعادة توجيه مفتوحة.

    جزء

    لا يمكن أن تحتوي عناوين URL لإعادة التوجيه على مكوِّن الجزء.

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

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

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

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

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

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

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

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

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

    لغة PHP

    $client->setIncludeGrantedScopes(true);

    لغة Python

    في 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"، يحدِّث كائن العميل رمز الدخول حسب الحاجة طالما أنك تهيئ هذا العنصر للوصول بلا اتصال بالإنترنت.
    • إذا كنت لا تستخدم مكتبة عميل، عليك ضبط معلمة طلب بحث HTTP access_type على offline عند إعادة توجيه المستخدم إلى خادم OAuth 2.0 في Google. وفي هذه الحالة، يعرض خادم تفويض Google رمزًا مميزًا لإعادة التحميل عند استبدال رمز تفويض برمز دخول. وإذا انتهت صلاحية رمز الدخول (أو في أي وقت آخر)، يمكنك استخدام رمز مميز لإعادة التحميل للحصول على رمز دخول جديد.

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

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

    لغة PHP

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

    $client->setAccessType("offline");

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

    لغة Python

    في 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 مع رمز خطأ.