يوضح هذا المستند كيفية استخدام تطبيقات خادم الويب لمكتبات برامج Google API أو نقاط نهاية OAuth 2.0 لتنفيذ تفويض OAuth 2.0 للوصول YouTube Data API.
يتيح بروتوكول OAuth 2.0 للمستخدمين مشاركة بيانات محددة مع أحد التطبيقات مع الاحتفاظ أسماء المستخدمين وكلمات المرور وغيرها من المعلومات بخصوصية تامّة. على سبيل المثال، يمكن لأحد التطبيقات استخدام OAuth 2.0 للحصول على إذن تحميل فيديوهات إلى قناة المستخدم على YouTube
تم إعداد مسار OAuth 2.0 هذا تحديدًا لتفويض المستخدم. فهي مصممة للتطبيقات يمكنه تخزين المعلومات السرية والحفاظ على حالتها. خادم ويب معتمد بشكل صحيح يمكن للتطبيق الوصول إلى واجهة برمجة التطبيقات أثناء تفاعل المستخدم مع التطبيق أو بعد تفاعل المستخدم غادر التطبيق.
تستخدم تطبيقات خادم الويب بشكل متكرر أيضًا
لحسابات الخدمة للسماح بطلبات البيانات من واجهة برمجة التطبيقات، وخاصةً عند طلب بيانات من Cloud APIs للوصول إلى
البيانات القائمة على المشروع بدلاً من البيانات الخاصة بالمستخدم. يمكن لتطبيقات خادم الويب استخدام الخدمة
مع تفويض المستخدم.
تجدر الإشارة إلى أنّ YouTube Data API تتيح تدفق حساب الخدمة فقط
مالكو المحتوى على YouTube الذين يملكون قنوات متعدّدة على YouTube ويديرونها.
على وجه التحديد، يمكن لمالكي المحتوى استخدام حسابات الخدمة لاستدعاء طرق واجهة برمجة التطبيقات التي
تدعم معلمة طلب onBehalfOfContentOwner
.
مكتبات العملاء
تستخدم الأمثلة الخاصة باللغة في هذه الصفحة مكتبات عميل Google API لتنفيذها تفويض OAuth 2.0. لتشغيل عيّنات التعليمات البرمجية، يجب أولاً تثبيت ومكتبة البرامج بلغتك.
وعند استخدام مكتبة برامج Google API لمعالجة مسار OAuth 2.0 لتطبيقك، سيتعامل البرنامج مكتبة لتنفيذ العديد من الإجراءات التي قد يحتاج التطبيق إلى معالجتها تلقائيًا. بالنسبة على سبيل المثال، يحدد متى يمكن للتطبيق استخدام رموز الدخول المخزنة أو تحديثها بالإضافة إلى الوقت الذي يجب فيه الحصول على الموافقة من جديد. تنشئ مكتبة البرامج أيضًا عمليات إعادة توجيه صحيحة. عناوين URL وتساعد في تنفيذ معالِجات إعادة التوجيه التي تتبادل رموز التفويض برموز الدخول.
تتوفر مكتبات برامج Google API للتطبيقات من جانب الخادم باللغات التالية:
المتطلبات الأساسية
تمكين واجهات برمجة التطبيقات لمشروعك
يحتاج أي تطبيق يستدعي واجهات Google APIs إلى تفعيل واجهات برمجة التطبيقات هذه في API Console
لتفعيل واجهة برمجة تطبيقات لمشروعك:
- Open the API Library في Google API Console
- If prompted, select a project, or create a new one.
- استخدِم صفحة المكتبة للعثور على YouTube Data API وتفعيلها. البحث عن أي تطبيق آخر هي واجهات برمجة التطبيقات التي سيستخدمها تطبيقك وتفعيلها أيضًا.
إنشاء بيانات اعتماد التفويض
يجب أن تكون بيانات اعتماد التفويض متاحة لأي تطبيق يستخدم 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، ننصحك بتحديد النطاقات سيحتاج تطبيقك إلى إذن للوصول إليه.
نقترح أيضًا أن يطلب تطبيقك الوصول إلى نطاقات التفويض من خلال التزايدية في عمليات التفويض، والتي يؤدي فيها تطبيقك يطلب الوصول إلى بيانات المستخدم في السياق. تساعد أفضل الممارسات هذه المستخدمين على فهم سبب احتياج تطبيقك إلى الوصول الذي يطلبه.
يستخدم الإصدار الثالث من YouTube Data API النطاقات التالية:
المناظير | |
---|---|
https://www.googleapis.com/auth/youtube | إدارة حسابك في YouTube |
https://www.googleapis.com/auth/youtube.channel-memberships.creator | الاطّلاع على قائمة بأعضاء القناة النشطين حاليًا ومستواهم الحالي وتاريخ انضمامهم |
https://www.googleapis.com/auth/youtube.force-ssl | الاطّلاع على فيديوهاتك على YouTube وتقييماتها وتعليقاتها وترجماتها وكذلك تعديلها وحذفها نهائيًا |
https://www.googleapis.com/auth/youtube.readonly | عرض حسابك في YouTube |
https://www.googleapis.com/auth/youtube.upload | إدارة فيديوهات YouTube |
https://www.googleapis.com/auth/youtubepartner | عرض وإدارة أصولك والمحتوى المرتبط بها على YouTube |
https://www.googleapis.com/auth/youtubepartner-channel-audit | عرض معلومات خاصة عن قناتك على YouTube ذات صلة أثناء عملية تدقيق شريك YouTube |
يحتوي مستند نطاقات واجهة برمجة تطبيقات OAuth 2.0 على رابط بالنطاقات التي قد تستخدمها للوصول إلى Google APIs.
المتطلبات الخاصة بكل لغة
لتشغيل أي من عينات التعليمات البرمجية في هذا المستند، ستحتاج إلى حساب Google، والوصول إلى إنترنت ومتصفّح ويب. إذا كنت تستخدم إحدى مكتبات عملاء واجهة برمجة التطبيقات، يمكنك أيضًا الاطّلاع على المتطلبات الخاصة بكل لغة أدناه.
PHP
لتشغيل نماذج كود PHP في هذا المستند، ستحتاج إلى:
- الإصدار 5.6 من PHP أو الإصدارات الأحدث مع تثبيت واجهة سطر الأوامر (CLI) وإضافة JSON.
- أداة إدارة الاعتمادية في المؤلف
-
مكتبة برامج Google APIs للغة PHP:
composer require google/apiclient:^2.10
Python
لتشغيل عيّنات التعليمات البرمجية للغة بايثون في هذا المستند، ستحتاج إلى:
- Python 2.6 أو أحدث
- أداة إدارة حزم pip
- مكتبة برامج Google APIs للغة Python:
pip install --upgrade google-api-python-client
google-auth
وgoogle-auth-oauthlib
google-auth-httplib2
لتفويض المستخدم.pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
- إطار عمل تطبيق الويب Flask Python.
pip install --upgrade flask
- مكتبة HTTP
requests
pip install --upgrade requests
Ruby
لتشغيل نماذج برمجة Ruby في هذا المستند، ستحتاج إلى:
- Ruby 2.6 أو أكبر
-
مكتبة مصادقة Google للغة Ruby:
gem install googleauth
-
إطار عمل تطبيق الويب Sinatra Ruby.
gem install sinatra
Node.js
لتشغيل نماذج التعليمات البرمجية Node.js في هذا المستند، ستحتاج إلى:
- قناة الدعم الطويل الأمد (LTS) أو قناة الدعم الطويل الأمد (LTS) النشطة أو الإصدار الحالي من Node.js.
-
عميل Node.js من Google APIs:
npm install googleapis crypto express express-session
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
على سبيل المثال، يطلب هذا الرمز الوصول بلا إنترنت لإدارة حساب المستخدم على YouTube. الحساب:
$client = new Google\Client(); // Required, call the setAuthConfig function to load authorization credentials from // client_secret.json file. $client->setAuthConfig('client_secret.json'); // Required, to set the scope value, call the addScope function $client->addScope(GOOGLE_SERVICE_YOUTUBE::YOUTUBE_FORCE_SSL); // Required, call the setRedirectUri function to specify a valid redirect URI for the // provided client_id $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); // Recommended, 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'); // Recommended, call the setState function. Using a state value can increase your assurance that // an incoming connection is the result of an authentication request. $client->setState($sample_passthrough_value); // Optional, if your application knows which user is trying to authenticate, it can use this // parameter to provide a hint to the Google Authentication Server. $client->setLoginHint('hint@example.com'); // Optional, call the setPrompt function to set "consent" will prompt the user for consent $client->setPrompt('consent'); // Optional, call the setIncludeGrantedScopes function with true to enable incremental // authorization $client->setIncludeGrantedScopes(true);
Python
يستخدم مقتطف الرمز التالي الوحدة google-auth-oauthlib.flow
لإنشاء
طلب التفويض.
ينشئ الرمز كائن Flow
، الذي يعرّف تطبيقك باستخدام
المعلومات من ملف client_secret.json الذي نزّلته بعد
إنشاء بيانات اعتماد التفويض. ويحدد هذا الكائن أيضًا
للنطاقات التي يطلب تطبيقك إذنًا بالوصول إليها وعنوان URL إلى عنوان URL
نقطة نهاية المصادقة، التي ستتعامل مع الاستجابة من خادم OAuth 2.0 من Google. أخيرًا، تسمح التعليمة البرمجية
تضبط المَعلمتَين access_type
وinclude_granted_scopes
الاختياريتَين.
على سبيل المثال، يطلب هذا الرمز الوصول بلا إنترنت لإدارة حساب المستخدم على YouTube. الحساب:
import google.oauth2.credentials import google_auth_oauthlib.flow # Required, call the from_client_secrets_file method to retrieve the client ID from a # client_secret.json file. The client ID (from that file) and access scopes are required. (You can # also use the from_client_config method, which passes the client configuration as it originally # appeared in a client secrets file but doesn't access the file itself.) flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/youtube.force-ssl']) # Required, 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( # Recommended, 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', # Optional, enable incremental authorization. Recommended as a best practice. include_granted_scopes='true', # Optional, if your application knows which user is trying to authenticate, it can use this # parameter to provide a hint to the Google Authentication Server. login_hint='hint@example.com', # Optional, set prompt to 'consent' will prompt the user for consent prompt='consent')
Ruby
استخدم ملف client_secrets.json الذي أنشأته لضبط كائن عميل في التطبيق. عند إعداد عنصر عميل، يمكنك تحديد النطاقات التي يحتاج تطبيقك إلى الدخول، إلى جانب عنوان URL لنقطة نهاية المصادقة في تطبيقك، والتي ستتعامل مع الاستجابة من خادم OAuth 2.0.
على سبيل المثال، يطلب هذا الرمز الوصول بلا إنترنت لإدارة حساب المستخدم على YouTube. الحساب:
require 'google/apis/youtube_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/youtube.force-ssl' token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')
يستخدم تطبيقك كائن العميل لإجراء عمليات OAuth 2.0، مثل إنشاء عناوين URL لطلب التفويض وتطبيق رموز الدخول على طلبات HTTP.
Node.js
ينشئ مقتطف الرمز التالي كائن google.auth.OAuth2
، الذي يحدد
المعلَمات في طلب التفويض.
ويستخدم هذا الكائن معلومات من ملف client_secret.json لتحديد تطبيقك. إلى طلب الأذونات من المستخدم لاسترداد رمز الدخول، تتم إعادة توجيهه إلى صفحة الموافقة. لإنشاء عنوان URL لصفحة الموافقة:
const {google} = require('googleapis'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * 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 secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // 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, // Include the state parameter to reduce the risk of CSRF attacks. state: state });
ملاحظة مهمة: لا يتم إرجاع 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 على المستخدم. تتيح النطاقات لتطبيقك طلب الوصول إلى الموارد التي يحتاج إليها فقط. مع تمكين المستخدمين أيضًا من التحكم في مقدار الوصول الذي يمنحونه إلى التطبيق. وبالتالي، توجد علاقة عكسية بين عدد النطاقات المطلوبة. واحتمالية الحصول على موافقة المستخدم. يستخدم الإصدار الثالث من YouTube Data API النطاقات التالية:
يوفر مستند نطاقات واجهة برمجة تطبيقات OAuth 2.0 قائمة كاملة بالنطاقات التي قد تستخدمها للوصول إلى واجهات برمجة تطبيقات Google. ننصح بأن يطلب تطبيقك الوصول إلى نطاقات التفويض في السياق. كلما أمكن ذلك. من خلال طلب الوصول إلى بيانات المستخدم في السياق، عبر تزايديًا، يمكنك مساعدة المستخدمين في فهم سبب احتياج تطبيقك إلى الوصول الذي يطلبه. |
||||||||||||||||
access_type |
مقترَح
يشير إلى ما إذا كان يمكن لتطبيقك إعادة تحميل رموز الدخول عند عدم حضور المستخدم
في المتصفح. قيم المَعلمات الصالحة هي عليك ضبط القيمة على |
||||||||||||||||
state |
مقترَح
تحدِّد هذه السياسة أي قيمة سلسلة يستخدمها تطبيقك للحفاظ على الحالة بين
طلب التفويض واستجابة خادم التفويض.
يعرض الخادم القيمة الدقيقة التي ترسلها كزوج ويمكنك استخدام هذه المعلمة لعدة أغراض، مثل توجيه المستخدم إلى الصفحة
المورد الصحيح في تطبيقك، وإرسال nonces، وتخفيف طلبات المواقع الإلكترونية المشتركة
التزوير. بما أنّه يمكن تخمين |
||||||||||||||||
include_granted_scopes |
اختياريّ
يعمل هذا الإعداد على السماح للتطبيقات باستخدام التفويض التزايدي لطلب الوصول إلى
والنطاقات في السياق. إذا ضبطت قيمة هذه المَعلمة على |
||||||||||||||||
enable_granular_consent |
اختياريّ
وتكون القيمة التلقائية هي وعند تفعيل Google لأذونات دقيقة لأحد التطبيقات، لن تترتب على هذه المعلَمة يكون لها أي تأثير. |
||||||||||||||||
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.redirect(authorizationUrl);
HTTP/REST
Sample redirect to Google's authorization server
The sample URL below requests offline access
(access_type=offline
) to a scope that permits access to view
the user's YouTube account. It uses incremental authorization to ensure that
the new access token covers any scopes to which the user previously granted
the application access. The URL also sets values for the required
redirect_uri
, response_type
, and
client_id
parameters as well as for the state
parameter. The URL contains line breaks and spaces for readability.
https://accounts.google.com/o/oauth2/v2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&
access_type=offline&
include_granted_scopes=true&
state=state_parameter_passthrough_value&
redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
response_type=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
يتم عرض نقطة نهاية التفويض داخل وكيل مستخدم مضمّن غير مسموح به من قِبل Google سياسات OAuth 2.0.
Android
قد تظهر رسالة الخطأ هذه لمطوِّري تطبيقات Android عند فتح طلبات الحصول على إذن في
android.webkit.WebView
وبدلاً من ذلك، على المطوّرين استخدام مكتبات Android مثل
تسجيل الدخول باستخدام حساب Google لنظام التشغيل Android أو OpenID Foundation
تطبيق AppAuth لنظام التشغيل Android
قد يواجه مطوّرو الويب هذا الخطأ عندما يفتح تطبيق Android رابط ويب عامًا في وكيل مستخدم مضمن وينتقل المستخدم إلى نقطة نهاية تفويض OAuth 2.0 في Google من موقعك الإلكتروني. على المطوّرين السماح بفتح الروابط العامة في معالِج الروابط التلقائي نظام التشغيل، والذي يشمل كلاً من Android App Links المستخدم أو تطبيق المتصفح الافتراضي. تشير رسالة الأشكال البيانية علامات التبويب المخصَّصة في Android المكتبة خيارًا متوافقًا.
iOS
قد يواجه مطوّرو iOS وmacOS هذا الخطأ عند فتح طلبات التفويض في
WKWebView
وبدلاً من ذلك، يجب أن يستخدم المطوّرون مكتبات iOS مثل
تسجيل الدخول باستخدام حساب Google لأجهزة iOS أو OpenID Foundation
تطبيق AppAuth لنظام التشغيل iOS
قد يظهر هذا الخطأ لمطوِّري الويب عندما يفتح تطبيق iOS أو macOS رابط ويب عامًا في
وكيل مستخدم مضمن وينتقل المستخدم إلى نقطة نهاية تفويض OAuth 2.0 في Google من
موقعك الإلكتروني. على المطوّرين السماح بفتح الروابط العامة في معالِج الروابط التلقائي
نظام التشغيل، والذي يشمل كلاً من
الروابط العامة
المستخدم أو تطبيق المتصفح الافتراضي. تشير رسالة الأشكال البيانية
SFSafariViewController
المكتبة خيارًا متوافقًا.
org_internal
معرِّف عميل OAuth في الطلب هو جزء من مشروع يحدّ من إمكانية الوصول إلى حسابات Google في محددة مؤسسة Google Cloud: لمزيد من المعلومات حول خيار التهيئة هذا، راجع نوع المستخدِم في مقالة المساعدة "إعداد شاشة طلب الموافقة المتعلقة ببروتوكول OAuth".
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%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly& access_type=offline& include_granted_scopes=true& state=state_parameter_passthrough_value& redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback& response_type=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/youtube.force-ssl'], 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. app.get('/oauth2callback', async (req, res) => { 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 if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // 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
في الطلب الأولي إلى
خادم التفويض.
يحتوي الردّ على الحقول التالية:
الحقول | |
---|---|
access_token |
الرمز المميز الذي يرسله تطبيقك لمصادقة طلب واجهة برمجة تطبيقات Google. |
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/youtube.force-ssl", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
الأخطاء
عند استبدال رمز التفويض برمز دخول، قد تواجه ما يلي: بدلاً من الاستجابة المتوقعة. رموز الخطأ الشائعة والحلول المقترحة هي الواردة أدناه.
invalid_grant
رمز التفويض المُقدَّم غير صالح أو بتنسيق غير صحيح. طلب رمز جديد بحلول إعادة بدء عملية OAuth لطلب الموافقة من المستخدم مرة أخرى.
الاتصال بـ Google APIs
PHP
استخدم رمز الدخول لاستدعاء Google APIs من خلال إكمال الخطوات التالية:
- إذا احتجت إلى تطبيق رمز دخول على عنصر
Google\Client
جديد — في على سبيل المثال، إذا خزّنت رمز الدخول في جلسة مستخدم، يمكنك استخدام طريقةsetAccessToken
:$client->setAccessToken($access_token);
- أنشِئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها. يمكنك إنشاء كائن خدمة من خلال
توفير عنصر
Google\Client
معتمد للأداة الإنشائية لواجهة برمجة التطبيقات التي تريد الاتصال به. على سبيل المثال، لطلب بيانات YouTube Data API:$youtube = new Google_Service_YouTube($client);
- يمكنك تقديم طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام
الواجهة التي يوفّرها عنصر الخدمة
على سبيل المثال، لاسترداد بيانات عن قناة المستخدم المصرح لها على YouTube:
$channel = $youtube->channels->listChannels('snippet', array('mine' => $mine));
Python
بعد الحصول على رمز الدخول، يمكن لتطبيقك استخدام ذلك الرمز لمصادقة طلبات واجهة برمجة التطبيقات على نيابةً عن حساب مستخدم أو حساب خدمة معيّن. استخدام بيانات اعتماد التفويض الخاصة بالمستخدم لإنشاء كائن خدمة لواجهة برمجة التطبيقات التي تريد طلبها، ثم استخدام ذلك الكائن لإنشاء المسموح بها من خلال واجهة برمجة التطبيقات.
- أنشِئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها. يمكنك إنشاء كائن خدمة من خلال
لاستدعاء طريقة
build
في مكتبةgoogleapiclient.discovery
باستخدام السمة اسم واجهة برمجة التطبيقات وإصدارها وبيانات اعتماد المستخدم: على سبيل المثال، لطلب الإصدار الثالث من YouTube Data API:from googleapiclient.discovery import build youtube = build('youtube', 'v3', credentials=credentials)
- يمكنك تقديم طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام
الواجهة التي يوفّرها عنصر الخدمة
على سبيل المثال، لاسترداد بيانات حول قناة المستخدم المصرح لها على YouTube:
channel = youtube.channels().list(mine=True, part='snippet').execute()
Ruby
بعد الحصول على رمز الدخول، يمكن لتطبيقك استخدام ذلك الرمز لإجراء طلبات البيانات من واجهة برمجة التطبيقات على نيابةً عن حساب مستخدم أو حساب خدمة معيّن. استخدام بيانات اعتماد التفويض الخاصة بالمستخدم لإنشاء كائن خدمة لواجهة برمجة التطبيقات التي تريد طلبها، ثم استخدام ذلك الكائن لإنشاء المسموح بها من خلال واجهة برمجة التطبيقات.
- أنشِئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها.
على سبيل المثال، لطلب الإصدار الثالث من YouTube Data API:
youtube = Google::Apis::YoutubeV3::YouTubeService.new
- اضبط بيانات الاعتماد في الخدمة:
youtube.authorization = credentials
- يمكنك تقديم طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام
واجهة
التي يقدّمها عنصر الخدمة
على سبيل المثال، لاسترداد بيانات حول قناة المستخدم المصرح لها على YouTube:
channel = youtube.list_channels(part, :mine => mine)
بدلاً من ذلك، يمكن توفير التفويض على أساس كل طريقة عن طريق تقديم
معلَمة options
إلى طريقة معيّنة:
channel = youtube.list_channels(part, :mine => mine, options: { authorization: auth_client })
Node.js
بعد الحصول على رمز الدخول وضبطه على الكائن OAuth2
، يمكنك استخدام الكائن.
لاستدعاء Google APIs. يمكن لتطبيقك استخدام هذا الرمز المميّز لمصادقة طلبات البيانات من واجهة برمجة التطبيقات نيابةً عن
حساب مستخدم أو حساب خدمة معيّن أنشِئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها.
const { google } = require('googleapis'); // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } });
HTTP/REST
بعد حصول تطبيقك على رمز الدخول، يمكنك استخدام الرمز لإجراء اتصالات
واجهة برمجة التطبيقات نيابةً عن مستخدم معيّن
حساب مستخدم في حال منح نطاقات الوصول التي تطلبها واجهة برمجة التطبيقات. للقيام بذلك، قم بتضمين
رمز الدخول في طلب إلى واجهة برمجة التطبيقات عن طريق تضمين طلب بحث access_token
مَعلمة أو قيمة Bearer
لعنوان HTTP يتضمّن Authorization
. عندما يكون ذلك ممكنًا،
ويُفضل استخدام عنوان HTTP، لأن سلاسل طلبات البحث غالبًا ما تكون مرئية في سجلات الخادم. في معظم
يمكنك استخدام مكتبة برامج لإعداد الطلبات إلى Google APIs (على سبيل المثال، عند
في YouTube Data API).
تجدر الإشارة إلى أنّ YouTube Data API تتيح حسابات الخدمة لمنصة YouTube فقط. مالكو المحتوى الذين يملكون قنوات متعددة على YouTube ويديرونها، مثل سجلات وشركات الإنتاج واستوديوهات الأفلام.
يمكنك تجربة جميع واجهات Google APIs وعرض نطاقاتها من خلال ملعب OAuth 2.0.
أمثلة على الحصول على HTTP
اتصال
youtube.channels
نقطة نهاية (YouTube Data API) باستخدام Authorization: Bearer
HTTP
على النحو التالي. ملاحظة: يجب تحديد رمز الدخول الخاص بك:
GET /youtube/v3/channels?part=snippet&mine=true HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
إليك طلب بيانات من واجهة برمجة التطبيقات نفسها للمستخدم الذي تمت مصادقته باستخدام access_token
مَعلمة سلسلة طلب البحث:
GET https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true
أمثلة على curl
يمكنك اختبار هذه الأوامر باستخدام تطبيق سطر الأوامر curl
. إليك
مثال يستخدم خيار عنوان HTTP (مفضّل):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true
أو بدلاً من ذلك، خيار مَعلمة سلسلة طلب البحث:
curl https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true
المثال الكامل
يطبع المثال التالي كائنًا بتنسيق JSON يعرض المعلومات حول قناة المستخدم على YouTube بعد أن يصادق المستخدم ويفوّضه لإدارة حساب المستخدم على YouTube.
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. إذا كنت تستخدم PHP 5.6 أو إصدارًا أحدث، فيجب
استخدام خادم الويب التجريبي المدمج بلغة 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_YOUTUBE::YOUTUBE_FORCE_SSL); if (isset($_SESSION['access_token']) && $_SESSION['access_token']) { $client->setAccessToken($_SESSION['access_token']); $youtube = new Google_Service_YouTube($client); $channel = $youtube->channels->listChannels('snippet', array('mine' => $mine)); echo json_encode($channel); } 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_YOUTUBE::YOUTUBE_FORCE_SSL); if (! isset($_GET['code'])) { // Generate and set state value $state = bin2hex(random_bytes(16)); $client->setState($state); $_SESSION['state'] = $state; $auth_url = $client->createAuthUrl(); header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL)); } else { // Check the state value if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) { die('State mismatch. Possible CSRF attack.'); } $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/youtube.force-ssl'] API_SERVICE_NAME = 'youtube' API_VERSION = 'v3' 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']) youtube = googleapiclient.discovery.build( API_SERVICE_NAME, API_VERSION, credentials=credentials) channel = youtube.channels().list(mine=True, part='snippet').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(**channel) @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/youtube_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 youtube = Google::Apis::YoutubeV3::YouTubeService.new channel = youtube.list_channels(part, :mine => mine, options: { authorization: auth_client }) "<pre>#{JSON.pretty_generate(channel.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'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * 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' ]; /* 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 app = express(); app.use(session({ secret: 'your_secure_secret_key', // Replace with a strong secret resave: false, saveUninitialized: false, })); // Example on redirecting user to Google's OAuth 2.0 server. app.get('/', async (req, res) => { // Generate a secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // 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, // Include the state parameter to reduce the risk of CSRF attacks. state: state }); res.redirect(authorizationUrl); }); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { // 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 if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } 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 app.get('/revoke', async (req, res) => { // 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(); }); const server = http.createServer(app); server.listen(80); } main().catch(console.error);
HTTP/REST
يستخدم مثال Python هذا إطار العمل Flask ومكتبة الطلبات لعرض بروتوكول OAuth 2.0 تدفق الويب. ننصحك باستخدام مكتبة برامج Google API للغة Python في هذا المسار. ( مثال في علامة التبويب Python يستخدم مكتبة البرامج).
import json import flask import requests app = flask.Flask(__name__) CLIENT_ID = '123456789.apps.googleusercontent.com' CLIENT_SECRET = 'abc123' # Read from a file or environmental variable in a real app SCOPE = 'https://www.googleapis.com/auth/youtube.force-ssl' 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/youtube/v3/channels/list' r = requests.get(req_uri, headers=headers) return r.text @app.route('/oauth2callback') def oauth2callback(): if 'code' not in flask.request.args: state = str(uuid.uuid4()) flask.session['state'] = state auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code' '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI, SCOPE, state) return flask.redirect(auth_uri) else: if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']: return 'State mismatch. Possible CSRF attack.', 400 auth_code = flask.request.args.get('code') data = {'code': auth_code, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'redirect_uri': REDIRECT_URI, 'grant_type': 'authorization_code'} r = requests.post('https://oauth2.googleapis.com/token', data=data) flask.session['credentials'] = r.text return flask.redirect(flask.url_for('index')) if __name__ == '__main__': import uuid app.secret_key = str(uuid.uuid4()) app.debug = False app.run()
إعادة توجيه قواعد التحقق من معرف الموارد المنتظم (URI)
يطبِّق محرّك بحث Google قواعد التحقق التالية لإعادة توجيه معرّفات الموارد المنتظمة (URI) لمساعدة المطوّرين. الحفاظ على أمان تطبيقاتهم. يجب أن تتقيّد معرفات الموارد المنتظمة (URI) لإعادة التوجيه بهذه القواعد. عرض الفقرة 3 من معيار RFC 3986 بشأن تعريف النطاق والمضيف والمسار والاستعلام والمخطط ومعلومات المستخدم أدناه.
قواعد التحقّق من الصحة | |
---|---|
المخطط |
يجب أن تستخدم معرّفات الموارد المنتظمة (URI) لإعادة التوجيه مخطط HTTPS، وليس HTTP العادي. معرفات الموارد المنتظمة (URI) للمضيف المحلي (بما في ذلك معرّفات الموارد المنتظمة (URI) لعنوان IP للمضيف المحلي) مستثناة من هذه القاعدة. |
المضيف |
لا يمكن للمضيفين أن يكونوا عناوين IP غير معدّلة. تُستثنى من هذه القاعدة عناوين IP للمضيف المحلي. |
النطاق |
“googleusercontent.com” .goo.gl ) ما لم
امتلاك التطبيق للنطاق. علاوة على ذلك، إذا اختار أي تطبيق يمتلك نطاقًا أقصر
إلى هذا النطاق، فإن عنوان URI لإعادة التوجيه هذا يجب أن يحتوي على
“/google-callback/” في مساره أو ينتهي بـ
“/google-callback” |
معلومات المستخدم |
لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) الخاصة بإعادة التوجيه على المكوِّن الفرعي لـ userinfo. |
المسار |
لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على اجتياز مسار (يسمى أيضًا تراجع الدليل).
الذي يمثله |
طلب بحث |
لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على عمليات إعادة التوجيه المفتوحة. |
الجزء |
لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على المكوِّن. |
الشخصيات |
لا يمكن أن تحتوي معرّفات الموارد المنتظمة (URI) لإعادة التوجيه على أحرف معيّنة، من بينها:
|
التفويض التزايدي
في بروتوكول OAuth 2.0، يطلب تطبيقك إذنًا للوصول إلى الموارد، وهي المحددة من خلال النطاقات. إنّ طلب الحصول على إذن هو من أفضل الممارسات للحفاظ على تجربة المستخدم. للموارد في الوقت الذي تحتاج فيه إليها. ولتفعيل هذه العملية، يستخدم خادم تفويض Google يدعم التفويض التزايدي. وتتيح لك هذه الميزة طلب النطاقات حسب الحاجة. إذا منح المستخدم إذنًا للنطاق الجديد، فيعرض رمز تفويض ربما يكون مقابل رمز مميز يحتوي على جميع النطاقات التي منحها المستخدم المشروع.
على سبيل المثال، لنفترض أنّ أحد التطبيقات يساعد المستخدمين في تحديد الأحداث المحلية المثيرة للاهتمام. ويتيح التطبيق للمستخدمين مشاهدة فيديوهات عن الأحداث وتقييم الفيديوهات وإضافة مقاطع الفيديو إلى قوائم تشغيل. يمكن للمستخدمين أيضًا استخدام التطبيق لإضافة أحداث إلى حسابهم على Google. التقاويم.
في هذه الحالة، أثناء تسجيل الدخول، قد لا يحتاج التطبيق إلى الوصول إلى
وأي نطاقات. ومع ذلك، إذا حاول المستخدم تقييم فيديو، أضِف فيديو إلى
قائمة التشغيل أو تنفيذ إجراء آخر على YouTube، قد يطلب التطبيق الوصول إلى
النطاق https://www.googleapis.com/auth/youtube.force-ssl
.
وبالمثل، يمكن للتطبيق طلب الوصول إلى
نطاق https://www.googleapis.com/auth/calendar
إذا حاول المستخدم
لإضافة حدث في التقويم.
لتنفيذ التفويض التزايدي، يجب إكمال المسار العادي لطلب إذن الوصول. ولكن يجب التأكد من أن طلب التفويض يتضمن نطاقات تم منحها مسبقًا. هذا النمط لتطبيقك تفادي الاضطرار إلى إدارة رموز دخول متعددة.
تنطبق القواعد التالية على رمز الدخول الذي يتم الحصول عليه من تفويض متزايد:
- يمكن استخدام الرمز المميز للوصول إلى الموارد المقابلة لأي من النطاقات التي تم إدراجها في تفويض جديد ومجمع.
- عند استخدام رمز التحديث للتفويض المجمّع للحصول على رمز دخول،
ويمثل رمز الدخول التفويض المجمّع ويمكن استخدامه لأي من
تم تضمين
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
في هذا المثال، يطلب تطبيق الاتصال الوصول لاسترداد بيانات YouTube Analytics الخاصة بالمستخدم بالإضافة إلى أي حق وصول آخر سبق أن تم منحه للتطبيق.
GET https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly& access_type=offline& state=security_token%3D138rk%3Btarget_url%3Dhttp...index& redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback& response_type=code& client_id=client_id& include_granted_scopes=true
Refreshing an access token (offline access)
Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.
- If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
- If you are not using a client library, you need to set the
access_type
HTTP query parameter tooffline
when redirecting the user to Google's OAuth 2.0 server. In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.
Requesting offline access is a requirement for any application that needs to access a Google
API when the user is not present. For example, an app that performs backup services or
executes actions at predetermined times needs to be able to refresh its access token when the
user is not present. The default style of access is called online
.
Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.
PHP
If your application needs offline access to a Google API, set the API client's access type to
offline
:
$client->setAccessType("offline");
بعد أن يمنح أحد المستخدمين الإذن بالوصول بلا إنترنت إلى النطاقات المطلوبة، يمكنك مواصلة استخدام واجهة برمجة التطبيقات. الوصول إلى Google APIs نيابةً عن المستخدم عندما يكون غير متصل بالإنترنت. كائن العميل سيقوم بتحديث رمز الدخول حسب الحاجة.
Python
في بايثون، اضبط وسيطة الكلمة الرئيسية access_type
على offline
لضمان
أنّك ستكون قادرًا على تحديث رمز الدخول دون الحاجة إلى أن تطلب من المستخدم مرة أخرى
إذن. من المحتمل جدًا ألا تكون access_type
هي الكلمة الرئيسية الوحيدة
التي حددتها، كما هو موضح في المثال أدناه.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
بعد أن يمنح أحد المستخدمين الإذن بالوصول بلا إنترنت إلى النطاقات المطلوبة، يمكنك مواصلة استخدام واجهة برمجة التطبيقات. الوصول إلى Google APIs نيابةً عن المستخدم عندما يكون غير متصل بالإنترنت. كائن العميل سيقوم بتحديث رمز الدخول حسب الحاجة.
Ruby
إذا كان تطبيقك يحتاج إلى الوصول بلا اتصال بالإنترنت إلى واجهة برمجة تطبيقات Google، اضبط نوع وصول عميل واجهة برمجة التطبيقات على
offline
:
auth_client.update!( :additional_parameters => {"access_type" => "offline"} )
بعد أن يمنح أحد المستخدمين الإذن بالوصول بلا إنترنت إلى النطاقات المطلوبة، يمكنك مواصلة استخدام واجهة برمجة التطبيقات. الوصول إلى Google APIs نيابةً عن المستخدم عندما يكون غير متصل بالإنترنت. كائن العميل سيقوم بتحديث رمز الدخول حسب الحاجة.
Node.js
إذا كان تطبيقك يحتاج إلى الوصول بلا اتصال بالإنترنت إلى واجهة برمجة تطبيقات Google، اضبط نوع وصول عميل واجهة برمجة التطبيقات على
offline
:
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
بعد أن يمنح أحد المستخدمين الإذن بالوصول بلا إنترنت إلى النطاقات المطلوبة، يمكنك مواصلة استخدام واجهة برمجة التطبيقات. الوصول إلى Google APIs نيابةً عن المستخدم عندما يكون غير متصل بالإنترنت. كائن العميل سيقوم بتحديث رمز الدخول حسب الحاجة.
تنتهي صلاحية رموز الدخول. ستستخدم هذه المكتبة تلقائيًا رمز مميّز لإعادة التحميل من أجل الحصول على إذن وصول جديد. إذا كانت على وشك انتهاء صلاحيتها. طريقة سهلة للتأكد من تخزين أحدث الرموز المميّزة دائمًا هو استخدام حدث الرموز المميزة:
oauth2Client.on('tokens', (tokens) => { if (tokens.refresh_token) { // store the refresh_token in your secure persistent database console.log(tokens.refresh_token); } console.log(tokens.access_token); });
ولا يحدث حدث الرموز المميزة هذا إلا في التفويض الأول، ويجب تعيين
من access_type
إلى offline
عند الاتصال برقم generateAuthUrl
لتلقي الرمز المميز للتحديث. إذا سبق لك منح التطبيق الأذونات المطلوبة
بدون وضع القيود المناسبة لتلقّي الرمز المميّز لإعادة التحميل، عليك
أعِد تفويض التطبيق لتلقّي رمز مميّز جديد لإعادة التحميل.
لضبط refresh_token
في وقت لاحق، يمكنك استخدام طريقة setCredentials
:
oauth2Client.setCredentials({ refresh_token: `STORED_REFRESH_TOKEN` });
بعد حصول العميل على رمز مميّز لإعادة التحميل، سيتم الحصول على رموز الدخول وإعادة تحميلها تلقائيًا. في الاتصال التالي بواجهة برمجة التطبيقات.
HTTP/REST
لإعادة تحميل رمز دخول، يرسل تطبيقك رمز HTTPS POST
.
إلى خادم تفويض Google (https://oauth2.googleapis.com/token
) بأنه
يتضمن المعلَمات التالية:
الحقول | |
---|---|
client_id |
معرّف العميل الذي تم الحصول عليه من API Console. |
client_secret |
سر العميل الذي تم الحصول عليه من API Console. |
grant_type |
بالنسبة
المحددة في
مواصفات OAuth 2.0،
يجب ضبط قيمة هذا الحقل على refresh_token . |
refresh_token |
الرمز المميّز لإعادة التحميل الذي يظهر من تبادل رمز التفويض |
يعرض المقتطف التالي نموذج طلب:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=your_client_id& client_secret=your_client_secret& refresh_token=refresh_token& grant_type=refresh_token
طالما لم يُبطل المستخدم إذن الوصول الممنوح للتطبيق، يستخدم خادم الرمز المميز تعرض كائن JSON يحتوي على رمز دخول جديد. يعرض المقتطف التالي عيّنة. الرد:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "token_type": "Bearer" }
لاحظ أن هناك حدودًا على عدد الرموز المميزة لإعادة التحميل التي سيتم إصدارها؛ حد واحد لكل مجموعة العميل/المستخدم، ومجموعة أخرى لكل مستخدم عبر جميع البرامج. يجب حفظ الرموز المميّزة لإعادة التحميل في مساحة التخزين طويلة الأجل ومواصلة استخدامها طالما أنها لا تزال صالحة. إذا كان طلبك يطلب عددًا كبيرًا جدًا من الرموز المميزة للتحديث، قد ينحصر في هذه الحدود، وفي هذه الحالة قد تظهر رموز تحديث عن العمل.
إبطال رمز مميّز
في بعض الحالات، قد يرغب المستخدم في إبطال إذن الوصول الممنوح لأحد التطبيقات. يمكن للمستخدم إبطال إذن الوصول عن طريق زيارة إعدادات الحساب يمكنك الاطّلاع على إزالة الوصول إلى الموقع الإلكتروني أو التطبيق ضمن مواقع الجهات الخارجية التطبيقات التي يمكنها الوصول إلى حسابك مستند الدعم للحصول على مزيد من المعلومات.
يمكن أيضًا لأحد التطبيقات إبطال إذن الوصول الممنوح له آليًا. يُعد الإبطال الآلي مهمًا في الحالات التي يلغي فيها المستخدم اشتراكه، أو يزيل أو تغيرت بشكل كبير موارد واجهة برمجة التطبيقات التي يتطلبها التطبيق. أو بعبارةٍ أخرى، أن يتضمن جزء من عملية الإزالة طلب بيانات من واجهة برمجة التطبيقات لضمان الحصول على الأذونات ممنوح للتطبيق.
PHP
لإبطال رمز مميّز آليًا، يمكنك الاتصال بالرقم revokeToken()
:
$client->revokeToken();
Python
لإبطال رمز مميّز آليًا، يمكنك إرسال طلب إلى
https://oauth2.googleapis.com/revoke
الذي يتضمّن الرمز المميّز كمَعلمة ويضبط
عنوان Content-Type
:
requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'})
Ruby
لإبطال رمز مميّز آليًا، يمكنك إرسال طلب HTTP إلى oauth2.revoke
.
نقطة النهاية:
uri = URI('https://oauth2.googleapis.com/revoke') response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
يمكن أن يكون الرمز المميز رمز دخول أو رمزًا مميزًا لإعادة التحميل. إذا كان الرمز عبارة عن رمز دخول وكان له رمز تحديث مميز، سيتم إبطال الرمز المميز للتحديث أيضًا.
إذا تمت معالجة الإبطال بنجاح، فسيكون رمز حالة الاستجابة هو
200
بالنسبة إلى حالات الخطأ، يتم عرض رمز الحالة 400
مع
رمز الخطأ.
Node.js
لإبطال رمز مميّز آليًا، يمكنك تقديم طلب HTTPS POST إلى /revoke
.
نقطة النهاية:
const https = require('https'); // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end();
يمكن أن تكون مَعلمة الرمز المميّز رمزًا للدخول أو رمزًا مميّزًا لإعادة التحميل. إذا كان الرمز عبارة عن رمز دخول وكان له رمز تحديث مميز، سيتم إبطال الرمز المميز للتحديث أيضًا.
إذا تمت معالجة الإبطال بنجاح، فسيكون رمز حالة الاستجابة هو
200
بالنسبة إلى حالات الخطأ، يتم عرض رمز الحالة 400
مع
رمز الخطأ.
HTTP/REST
لإبطال رمز مميّز آليًا، يطلب تطبيقك
https://oauth2.googleapis.com/revoke
وتتضمّن الرمز المميّز كمَعلمة:
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token={token}
يمكن أن يكون الرمز المميز رمز دخول أو رمزًا مميزًا لإعادة التحميل. إذا كان الرمز المميز عبارة عن رمز دخول وكان له الرمز المميز المقابل للتحديث، سيتم أيضًا إبطال الرمز المميز للتحديث.
إذا تمت معالجة الإبطال بنجاح، فسيتم عندئذٍ رمز حالة HTTP للاستجابة
200
بالنسبة إلى حالات الخطأ، يتم عرض رمز حالة HTTP 400
مع
مع رمز خطأ.
تطبيق ميزة "الحماية العابرة للحساب"
خطوة إضافية ينبغي لك اتخاذها لحماية حسابات المستخدمين الحسابات تنفّذ ميزة "على مستوى الحساب" يمكنك الحماية باستخدام "خدمة الحماية العابرة للحساب" من Google. تتيح لك هذه الخدمة الاشتراك في إشعارات الأحداث الأمنية التي تقدّم معلومات إلى تطبيقك حول التغييرات الرئيسية التي تطرأ على حساب المستخدم. ويمكنك بعد ذلك استخدام المعلومات لاتخاذ إجراء استنادًا إلى وكيف تقرر الرد على الأحداث.
في ما يلي بعض الأمثلة على أنواع الأحداث التي ترسلها "خدمة الحماية العابرة للحساب" من Google إلى تطبيقك:
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
-
https://schemas.openid.net/secevent/oauth/event-type/token-revoked
-
https://schemas.openid.net/secevent/risc/event-type/account-disabled
يمكنك الاطّلاع على حماية حسابات المستخدمين باستخدام صفحة "الحماية العابرة للحساب" للحصول على مزيد من المعلومات حول كيفية تفعيل ميزة "الحماية العابرة للحساب" والاطّلاع على قائمة كاملة بالأحداث المتاحة.