استخدام 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 API للتطبيقات من جهة الخادم باللغات التالية:

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

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

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

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

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

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

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

  1. Go to the Credentials page.
  2. انقر على إنشاء بيانات اعتماد > معرِّف عميل OAuth.
  3. اختَر نوع تطبيق تطبيق الويب.
  4. املأ النموذج وانقر على إنشاء. إنّ التطبيقات التي تستخدم لغات وأُطر عمل، مثل لغة PHP وJava وPython وRuby و .NET، يجب أن تحدّد معرّفات موارد منتظمة (URI) مُعتمَدة. معرّفات الموارد المنتظمة (URI) لإعادة التوجيه هي نقاط النهاية التي يمكن لخادم OAuth 2.0 إرسال الردود إليها. ويجب أن تتقيّد نقاط النهاية هذه بقواعد التحقّق من Google.

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

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

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

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

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

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

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

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

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

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

PHP

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

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

    composer require google/apiclient:^2.10

Python

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

  • الإصدار 2.6 أو إصدار أحدث من Python
  • أداة إدارة الحزمة 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 البرمجية في هذا المستند، ستحتاج إلى ما يلي:

  • الإصدار 2.6 أو إصدار أحدث من Ruby
  • مكتبة مصادقة 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 مطلوب

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

معرِّف العميل لتطبيقك. يمكنك العثور على هذه القيمة في 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 والحالة والشرطة المائلة اللاحقة ('/').

لضبط هذه القيمة في بايثون، اضبط السمة 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 للحصول على مثال حول كيفية إنشاء رمز 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 مطلوب

معرِّف العميل لتطبيقك. يمكنك العثور على هذه القيمة في 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 للحصول على مثال حول كيفية إنشاء رمز 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 لأجهزة Android من OpenID Foundation.

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

iOS

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

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

org_internal

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

invalid_client

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

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

أمثلة على HTTP GET

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

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

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

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

أمثلة على curl

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

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

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

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

مثال كامل

في المثال التالي، تتم طباعة قائمة ملفات بتنسيق 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

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

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

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

المضيف

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

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

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

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