يوضّح هذا المستند كيف تستخدم تطبيقات خادم الويب مكتبات عميل 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.
لتفعيل واجهة برمجة تطبيقات لمشروعك:
- Open the API Library في Google API Console.
- If prompted, select a project, or create a new one.
- تعرض قائمة " API Library " جميع واجهات برمجة التطبيقات المتاحة، ويتم تجميعها حسب مجموعة المنتجات ومدى رواجها. إذا كانت واجهة برمجة التطبيقات التي تريد تفعيلها غير مرئية في القائمة، استخدِم البحث للعثور عليها، أو انقر على عرض الكل في مجموعة المنتجات التي تنتمي إليها.
- اختر واجهة برمجة التطبيقات التي تريد تفعيلها، ثم انقر على الزر تفعيل.
- If prompted, enable billing.
- If prompted, read and accept the API's Terms of Service.
إنشاء بيانات اعتماد التفويض
يجب أن يمتلك أي تطبيق يستخدم OAuth 2.0 للوصول إلى Google APIs بيانات اعتماد التفويض التي تحدّد التطبيق في خادم OAuth 2.0 من Google. توضّح الخطوات التالية كيفية إنشاء بيانات اعتماد لمشروعك. ويمكن لتطبيقاتك بعد ذلك استخدام بيانات الاعتماد للوصول إلى واجهات برمجة التطبيقات التي فعّلتها لهذا المشروع.
- Go to the Credentials page.
- انقر على إنشاء بيانات اعتماد > معرِّف عميل OAuth.
- اختَر نوع تطبيق تطبيق الويب.
- املأ النموذج وانقر على إنشاء. إنّ التطبيقات التي تستخدم لغات وأُطر عمل، مثل لغة 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 الذي يتطلب تفويض المستخدم.
تلخص القائمة أدناه الخطوات التالية بسرعة:
- يحدِّد التطبيق الأذونات التي يحتاج إليها.
- يُعيد تطبيقك توجيه المستخدم إلى Google مع قائمة الأذونات المطلوبة.
- يقرر المستخدم ما إذا كان يمنح الأذونات لتطبيقك أم لا.
- يكتشف تطبيقك ما قرره المستخدم.
- إذا منح المستخدم الأذونات المطلوبة، يسترد تطبيقك الرموز المميَّزة اللازمة لإجراء طلبات البيانات من واجهة برمجة التطبيقات نيابةً عن المستخدم.
الخطوة 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، يمكنك استدعاء الدالة $client = new Google\Client(); $client->setAuthConfig('client_secret.json'); |
||||||
redirect_uri |
مطلوب
تحدِّد هذه السياسة المواضع التي يُعيد فيها خادم واجهة برمجة التطبيقات توجيه المستخدم بعد أن يُكمل
عملية التفويض. يجب أن تتطابق القيمة بشكل تام مع أحد معرِّفات الموارد المنتظمة (URI) المُعتمَدة لإعادة التوجيه لبرنامج OAuth 2.0، والتي تم ضبطها في API Console
Credentials pageلعميلك. إذا لم تتطابق هذه القيمة مع
معرّف الموارد المنتظم (URI) المصرّح به لإعادة التوجيه للسمة يجب أن يتطابق المخطط لضبط هذه القيمة في PHP، يمكنك استدعاء الدالة $client->setRedirectUri('https://oauth2.example.com/code'); |
||||||
scope |
مطلوب
تمثّل هذه السمة قائمة النطاقات مع الفصل بينها بمسافات والتي تحدد الموارد التي يمكن لتطبيقك الوصول إليها نيابةً عن المستخدم. توضِّح هذه القيم شاشة طلب الموافقة التي يعرضها محرّك بحث Google للمستخدم. تمكّن النطاقات تطبيقك من طلب الوصول إلى الموارد التي يحتاج إليها فقط مع تمكين المستخدمين أيضًا من التحكم في مقدار الوصول الذي يمنحونه لتطبيقك. وبالتالي، هناك علاقة عكسية بين عدد النطاقات المطلوبة واحتمالية الحصول على موافقة المستخدم. لضبط هذه القيمة في PHP، يمكنك استدعاء الدالة $client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY); ننصح بأن يطلب تطبيقك الوصول إلى نطاقات التفويض في السياق كلما أمكن ذلك. إنّ طلب الوصول إلى بيانات المستخدمين في السياق المناسب من خلال التفويض الإضافي يساعد المستخدمين على معرفة سبب احتياج التطبيق إلى إذن الوصول الذي يطلبه بسهولة. |
||||||
access_type |
سمة مقترَحة
تشير إلى ما إذا كان بإمكان التطبيق إعادة تحميل رموز الدخول في حال عدم تواجد المستخدم في المتصفّح. قيم المَعلمات الصالحة هي اضبط القيمة على لضبط هذه القيمة في PHP، يمكنك استدعاء الدالة $client->setAccessType('offline'); |
||||||
state |
سمة مقترَحة
يحدِّد هذا الإعداد أي قيمة سلسلة يستخدمها تطبيقك للحفاظ على الحالة بين
طلب التفويض واستجابة خادم التفويض.
يعرض الخادم القيمة الدقيقة التي ترسلها كزوج يمكنك استخدام هذه المَعلمة لعدّة أغراض، مثل توجيه المستخدم إلى
المورد الصحيح في تطبيقك، وإرسال أرقام تعريفية، والحدّ من حالات تزوير الطلبات من مواقع إلكترونية متعددة. بما أنّه يمكن تخمين لضبط هذه القيمة في PHP، يمكنك استدعاء الدالة $client->setState($sample_passthrough_value); |
||||||
include_granted_scopes |
اختياريّ
تعمل هذه السياسة على تفعيل التطبيقات من استخدام التفويض المتزايد لطلب الوصول إلى
نطاقات إضافية في السياق. في حال ضبط قيمة هذه المَعلمة على لضبط هذه القيمة في PHP، يمكنك استدعاء الدالة $client->setIncludeGrantedScopes(true); |
||||||
enable_granular_consent |
اختياريّ
يكون الإعداد التلقائي بالقيمة |
||||||
login_hint |
اختياريّ
إذا كان تطبيقك يعرف المستخدم الذي يحاول المصادقة، يمكنه استخدام هذه المعلَمة لتقديم تلميح إلى خادم المصادقة في Google. ويستخدم الخادم التلميح لتبسيط عملية تسجيل الدخول، إما عن طريق ملء حقل البريد الإلكتروني مسبقًا في نموذج تسجيل الدخول أو عن طريق اختيار جلسة تسجيل الدخول المتعدد المناسبة. اضبط قيمة المَعلمة على عنوان بريد إلكتروني أو معرّف لضبط هذه القيمة في PHP، يمكنك استدعاء الدالة $client->setLoginHint('None'); |
||||||
prompt |
اختياريّ
قائمة بالمطالبات التي يتم الفصل بينها بمسافات وحساسة لحالة الأحرف، لتقديم طلب تقديم المستخدم. إذا لم تحدّد هذه المعلَمة، سيُطلب من المستخدم فقط في المرة الأولى التي يطلب فيها مشروعك الإذن بالوصول. راجِع طلب إعادة الموافقة للاطّلاع على مزيد من المعلومات. لضبط هذه القيمة في PHP، يمكنك استدعاء الدالة $client->setPrompt('consent'); القيم المتاحة هي:
|
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، يمكنك استدعاء الطريقة 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) المصرّح به لإعادة التوجيه للسمة يجب أن يتطابق المخطط لضبط هذه القيمة في بايثون، اضبط السمة flow.redirect_uri = 'https://oauth2.example.com/code' |
||||||
scope |
مطلوب
قائمة بالنطاقات التي تحدّد الموارد التي يمكن لتطبيقك الوصول إليها نيابةً عن المستخدم. توضِّح هذه القيم شاشة طلب الموافقة التي يعرضها محرّك بحث Google للمستخدم. تمكّن النطاقات تطبيقك من طلب الوصول إلى الموارد التي يحتاج إليها فقط مع تمكين المستخدمين أيضًا من التحكم في مقدار الوصول الذي يمنحونه لتطبيقك. وبالتالي، هناك علاقة عكسية بين عدد النطاقات المطلوبة واحتمالية الحصول على موافقة المستخدم. في بايثون، استخدِم الطريقة نفسها التي تستخدمها لضبط flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly']) ننصح بأن يطلب تطبيقك الوصول إلى نطاقات التفويض في السياق كلما أمكن ذلك. إنّ طلب الوصول إلى بيانات المستخدمين في السياق المناسب من خلال التفويض الإضافي يساعد المستخدمين على معرفة سبب احتياج التطبيق إلى إذن الوصول الذي يطلبه بسهولة. |
||||||
access_type |
سمة مقترَحة
تشير إلى ما إذا كان بإمكان التطبيق إعادة تحميل رموز الدخول في حال عدم تواجد المستخدم في المتصفّح. قيم المَعلمات الصالحة هي اضبط القيمة على في بايثون، اضبط المعلَمة authorization_url, state = flow.authorization_url( access_type='offline', include_granted_scopes='true') |
||||||
state |
سمة مقترَحة
يحدِّد هذا الإعداد أي قيمة سلسلة يستخدمها تطبيقك للحفاظ على الحالة بين
طلب التفويض واستجابة خادم التفويض.
يعرض الخادم القيمة الدقيقة التي ترسلها كزوج يمكنك استخدام هذه المَعلمة لعدّة أغراض، مثل توجيه المستخدم إلى
المورد الصحيح في تطبيقك، وإرسال أرقام تعريفية، والحدّ من حالات تزوير الطلبات من مواقع إلكترونية متعددة. بما أنّه يمكن تخمين في بايثون، اضبط المعلَمة authorization_url, state = flow.authorization_url( access_type='offline', state=sample_passthrough_value, include_granted_scopes='true') |
||||||
include_granted_scopes |
اختياريّ
تعمل هذه السياسة على تفعيل التطبيقات من استخدام التفويض المتزايد لطلب الوصول إلى
نطاقات إضافية في السياق. في حال ضبط قيمة هذه المَعلمة على في بايثون، اضبط المعلَمة authorization_url, state = flow.authorization_url( access_type='offline', include_granted_scopes='true') |
||||||
enable_granular_consent |
اختياريّ
يكون الإعداد التلقائي بالقيمة |
||||||
login_hint |
اختياريّ
إذا كان تطبيقك يعرف المستخدم الذي يحاول المصادقة، يمكنه استخدام هذه المعلَمة لتقديم تلميح إلى خادم المصادقة في Google. ويستخدم الخادم التلميح لتبسيط عملية تسجيل الدخول، إما عن طريق ملء حقل البريد الإلكتروني مسبقًا في نموذج تسجيل الدخول أو عن طريق اختيار جلسة تسجيل الدخول المتعدد المناسبة. اضبط قيمة المَعلمة على عنوان بريد إلكتروني أو معرّف في بايثون، اضبط المعلَمة authorization_url, state = flow.authorization_url( access_type='offline', login_hint='None', include_granted_scopes='true') |
||||||
prompt |
اختياريّ
قائمة بالمطالبات التي يتم الفصل بينها بمسافات وحساسة لحالة الأحرف، لتقديم طلب تقديم المستخدم. إذا لم تحدّد هذه المعلَمة، سيُطلب من المستخدم فقط في المرة الأولى التي يطلب فيها مشروعك الإذن بالوصول. راجِع طلب إعادة الموافقة للاطّلاع على مزيد من المعلومات. في بايثون، اضبط المعلَمة authorization_url, state = flow.authorization_url( access_type='offline', prompt='consent', include_granted_scopes='true') القيم المتاحة هي:
|
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) المصرّح به لإعادة التوجيه للسمة يجب أن يتطابق المخطط |
||||||
response_type |
مطلوب
تحدِّد هذه السياسة ما إذا كانت نقطة نهاية Google OAuth 2.0 تعرض رمز تفويض. اضبط قيمة المَعلمة على |
||||||
scope |
مطلوب
تمثّل هذه السمة قائمة النطاقات مع الفصل بينها بمسافات والتي تحدد الموارد التي يمكن لتطبيقك الوصول إليها نيابةً عن المستخدم. توضِّح هذه القيم شاشة طلب الموافقة التي يعرضها محرّك بحث Google للمستخدم. تمكّن النطاقات تطبيقك من طلب الوصول إلى الموارد التي يحتاج إليها فقط مع تمكين المستخدمين أيضًا من التحكم في مقدار الوصول الذي يمنحونه لتطبيقك. وبالتالي، هناك علاقة عكسية بين عدد النطاقات المطلوبة واحتمالية الحصول على موافقة المستخدم. ننصح بأن يطلب تطبيقك الوصول إلى نطاقات التفويض في السياق كلما أمكن ذلك. إنّ طلب الوصول إلى بيانات المستخدمين في السياق المناسب من خلال التفويض الإضافي يساعد المستخدمين على معرفة سبب احتياج التطبيق إلى إذن الوصول الذي يطلبه بسهولة. |
||||||
access_type |
سمة مقترَحة
تشير إلى ما إذا كان بإمكان التطبيق إعادة تحميل رموز الدخول في حال عدم تواجد المستخدم في المتصفّح. قيم المَعلمات الصالحة هي اضبط القيمة على |
||||||
state |
سمة مقترَحة
يحدِّد هذا الإعداد أي قيمة سلسلة يستخدمها تطبيقك للحفاظ على الحالة بين
طلب التفويض واستجابة خادم التفويض.
يعرض الخادم القيمة الدقيقة التي ترسلها كزوج يمكنك استخدام هذه المَعلمة لعدّة أغراض، مثل توجيه المستخدم إلى
المورد الصحيح في تطبيقك، وإرسال أرقام تعريفية، والحدّ من حالات تزوير الطلبات من مواقع إلكترونية متعددة. بما أنّه يمكن تخمين |
||||||
include_granted_scopes |
اختياريّ
تعمل هذه السياسة على تفعيل التطبيقات من استخدام التفويض المتزايد لطلب الوصول إلى
نطاقات إضافية في السياق. في حال ضبط قيمة هذه المَعلمة على |
||||||
enable_granular_consent |
اختياريّ
يكون الإعداد التلقائي بالقيمة |
||||||
login_hint |
اختياريّ
إذا كان تطبيقك يعرف المستخدم الذي يحاول المصادقة، يمكنه استخدام هذه المعلَمة لتقديم تلميح إلى خادم المصادقة في Google. ويستخدم الخادم التلميح لتبسيط عملية تسجيل الدخول، إما عن طريق ملء حقل البريد الإلكتروني مسبقًا في نموذج تسجيل الدخول أو عن طريق اختيار جلسة تسجيل الدخول المتعدد المناسبة. اضبط قيمة المَعلمة على عنوان بريد إلكتروني أو معرّف |
||||||
prompt |
اختياريّ
قائمة بالمطالبات التي يتم الفصل بينها بمسافات وحساسة لحالة الأحرف، لتقديم طلب تقديم المستخدم. إذا لم تحدّد هذه المعلَمة، سيُطلب من المستخدم فقط في المرة الأولى التي يطلب فيها مشروعك الإذن بالوصول. راجِع طلب إعادة الموافقة للاطّلاع على مزيد من المعلومات. القيم المتاحة هي:
|
الخطوة 2: إعادة التوجيه إلى خادم OAuth 2.0 من Google
أعِد توجيه المستخدم إلى خادم OAuth 2.0 من Google لبدء عملية المصادقة والترخيص. ويحدث ذلك عادةً عندما يحتاج التطبيق إلى الوصول إلى بيانات المستخدم لأول مرة. في حالة التفويض الإضافي، تحدث هذه الخطوة أيضًا عندما يحتاج التطبيق في البداية إلى الوصول إلى موارد إضافية ليس لديه إذن بالوصول إليها بعد.
PHP
- يمكنك إنشاء عنوان URL لطلب الوصول من خادم OAuth 2.0 من Google:
$auth_url = $client->createAuthUrl();
- إعادة توجيه المستخدم إلى
$auth_url
:header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
Python
يوضح هذا المثال كيفية إعادة توجيه المستخدم إلى عنوان URL للتفويض باستخدام إطار عمل تطبيق الويب Flask:
return flask.redirect(authorization_url)
Ruby
- يمكنك إنشاء عنوان URL لطلب الوصول من خادم OAuth 2.0 من Google:
auth_uri = authorizer.get_authorization_url(login_hint: user_id, request: request)
- إعادة توجيه المستخدم إلى
auth_uri
.
Node.js
-
استخدِم طريقة عنوان URL الذي تم إنشاؤه
authorizationUrl
من الخطوة 1generateAuthUrl
لطلب الوصول من خادم OAuth 2.0 على Google. -
إعادة توجيه المستخدم إلى
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 من خلال إكمال الخطوات التالية:
- إذا كنت بحاجة إلى تطبيق رمز دخول على عنصر
Google\Client
جديد، على سبيل المثال، إذا احتفظت برمز الدخول في جلسة مستخدم، استخدِم الطريقةsetAccessToken
:$client->setAccessToken($access_token);
- أنشئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها. يمكنك إنشاء كائن خدمة من خلال توفير كائن
Google\Client
مصرّح به إلى الدالة الإنشائية لواجهة برمجة التطبيقات التي تريد طلبها. على سبيل المثال، لطلب بيانات من Drive API:$drive = new Google\Service\Drive($client);
- يمكنك إرسال طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام الواجهة التي يوفّرها كائن الخدمة.
على سبيل المثال، لإدراج الملفات في Google Drive للمستخدم الذي تمت مصادقته:
$files = $drive->files->listFiles(array())->getItems();
Python
بعد الحصول على رمز الدخول، يمكن لتطبيقك استخدام ذلك الرمز المميّز للموافقة على طلبات البيانات من واجهة برمجة التطبيقات نيابةً عن حساب مستخدم أو حساب خدمة معيّن. استخدِم بيانات اعتماد التفويض الخاصة بالمستخدم لإنشاء كائن خدمة لواجهة برمجة التطبيقات التي تريد طلبها، ثم استخدِم هذا الكائن لإنشاء طلبات البيانات المصرّح بها من واجهة برمجة التطبيقات.
- أنشئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها. يمكنك إنشاء كائن خدمة من خلال
استدعاء الإجراء
build
لمكتبةgoogleapiclient.discovery
مع اسم إصدار واجهة برمجة التطبيقات وإصدارها وبيانات اعتماد المستخدم: على سبيل المثال، لطلب الإصدار 3 من Drive API:from googleapiclient.discovery import build drive = build('drive', 'v2', credentials=credentials)
- يمكنك إرسال طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام الواجهة التي يوفّرها كائن الخدمة.
على سبيل المثال، لإدراج الملفات في Google Drive للمستخدم الذي تمت مصادقته:
files = drive.files().list().execute()
Ruby
بعد الحصول على رمز الدخول، يمكن لتطبيقك استخدام هذا الرمز المميّز في تقديم طلبات من واجهة برمجة التطبيقات نيابةً عن حساب مستخدم أو حساب خدمة معيّن. استخدِم بيانات اعتماد التفويض الخاصة بالمستخدم لإنشاء كائن خدمة لواجهة برمجة التطبيقات التي تريد طلبها، ثم استخدِم هذا الكائن لإنشاء طلبات البيانات المصرّح بها من واجهة برمجة التطبيقات.
- أنشئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها.
على سبيل المثال، لاستدعاء الإصدار 3 من Drive API:
drive = Google::Apis::DriveV3::DriveService.new
- اضبط بيانات الاعتماد في الخدمة:
drive.authorization = credentials
- يمكنك إرسال طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام الواجهة التي يوفّرها كائن الخدمة.
على سبيل المثال، لإدراج الملفات في 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
لتشغيل هذا المثال:
- في API Console، أضِف عنوان URL للجهاز المحلي إلى قائمة عناوين URL لإعادة التوجيه. على سبيل المثال، يمكنك إضافة
http://localhost:8080
. - إنشاء دليل جديد والتغيير إليه مثلاً:
mkdir ~/php-oauth2-example cd ~/php-oauth2-example
- ثبِّت مكتبة برامج Google API للغة PHP باستخدام Composer:
composer require google/apiclient:^2.10
- أنشئ الملفين
index.php
وoauth2callback.php
باستخدام المحتوى أدناه. - شغِّل المثال مع خادم ويب تم إعداده لعرض لغة 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
لتشغيل هذا المثال:
-
في API Console، أضِف عنوان URL للجهاز المحلي إلى قائمة عناوين URL لإعادة التوجيه. على سبيل المثال، يمكنك إضافة
http://localhost
. - تأكَّد من تثبيت خدمة الدعم الطويل الأمد (LTS) أو الدعم الطويل الأمد (LTS) أو الإصدار الحالي من Node.js.
-
إنشاء دليل جديد والتغيير إليه مثلاً:
mkdir ~/nodejs-oauth2-example cd ~/nodejs-oauth2-example
-
Install the
Google API Client
Library
for Node.js using npm:
npm install googleapis
-
يمكنك إنشاء الملفات
main.js
باستخدام المحتوى أدناه. -
شغِّل المثال:
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 للمضيف المحلي من هذه القاعدة. |
النطاق |
“googleusercontent.com” .goo.gl ) ما لم يكن
التطبيق يملك النطاق. بالإضافة إلى ذلك، إذا اختار تطبيق يمتلك نطاقًا أقصر إعادة التوجيه إلى ذلك النطاق، يجب أن يحتوي معرّف الموارد المنتظم (URI) لإعادة التوجيه هذا على “/google-callback/” في مساره أو أن ينتهي بـ “/google-callback” . |
معلومات المستخدم |
لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على المكوّن الفرعي لمعلومات المستخدم. |
المسار |
لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على مسار (يُعرف أيضًا باسم "تتبُّع تراجع الدليل")، الذي يتم تمثيله من خلال |
طلب بحث |
لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على عمليات إعادة توجيه مفتوحة. |
جزء |
لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على مكوّن للجزء. |
الأحرف |
لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على أحرف معيّنة، بما في ذلك:
|
التفويض التزايدي
في بروتوكول 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
مع رمز خطأ.