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

<a href="/intl/ar/ads/">البرنامج الإعلاني</a> لمزيد من المعلومات، راجِع نظرة عامة على المصادقة في مستندات Google Cloud Platform.

يتوافق نظام Google OAuth 2.0 مع التفاعلات بين الخوادم، مثل التفاعلات بين تطبيقات الويب وخدمة Google. في هذا السيناريو، تحتاج إلى حساب خدمة، وهو حساب ينتمي إلى تطبيقك بدلاً من مستخدم فردي. يستدعي تطبيقك واجهات Google APIs بالنيابة عن حساب الخدمة، لذلك فإن المستخدمين لا يشتركون بشكل مباشر. يُطلق على هذا السيناريو أحيانًا "بروتوكول OAuth الثنائي&&; أو "2LO&" (العبارة ذات الصلة ""بروتوكول OAuth الثلاثي" تشير إلى سيناريوهات يستدعي تطبيقك فيها واجهات برمجة تطبيقات Google بالنيابة عن المستخدمين النهائيين، وتكون موافقة المستخدم مطلوبة فيها في بعض الأحيان.)

يستخدم التطبيق عادةً حساب خدمة عندما يستخدم التطبيق واجهات برمجة تطبيقات Google للعمل مع بياناته الخاصة بدلاً من بيانات المستخدم. على سبيل المثال، قد يستخدم تطبيق يستخدم Google Cloud Datastore للاحتفاظ بالبيانات للبيانات حساب خدمة لمصادقة طلبات البيانات الواردة إلى Google Cloud Datastore API.

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

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

نظرة عامة

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

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

وأخيرًا، يمكن لتطبيقك استخدام رمز الدخول لاستدعاء Google APIs.

إنشاء حساب خدمة

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

إذا كان يتم تشغيل تطبيقك على Google App Engine، يتم إعداد حساب الخدمة تلقائيًا عند إنشاء مشروعك.

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

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

أولاً ، قم بإنشاء حساب خدمة:

  1. فتح Service accounts page.
  2. If prompted, select a project, or create a new one.
  3. انقر أنشئ حسابا الخدمة.
  4. تحت تفاصيل حساب خدمة، اكتب اسما، ID، ووصف لحساب الخدمة، ثم انقر فوق إنشاء ومتابعة.
  5. اختياري: في ظل منح هذا الحساب وصول الخدمة للمشروع، وحدد الأدوار IAM منح لحساب الخدمة.
  6. انقر فوق متابعة.
  7. اختياري: في ظل منح المستخدمين الوصول إلى حساب خدمة هذا، إضافة المستخدمين أو المجموعات التي يسمح لاستخدام وإدارة حساب الخدمة.
  8. انقر فوق تم.
  9. انقر اصنع مفتاح، ثم انقر فوق إنشاء.

بعد ذلك ، قم بإنشاء مفتاح حساب الخدمة:

  1. انقر فوق عنوان البريد الإلكتروني لحساب الخدمة الذي أنشأته.
  2. انقر فوق علامة التبويب مفاتيح.
  3. في القائمة المنسدلة إضافة مفتاح، حدد إنشاء مفتاح جديد.
  4. انقر فوق إنشاء.

يتم إنشاء زوج المفاتيح العام / الخاص الجديد وتنزيله على جهازك ؛ إنه بمثابة النسخة الوحيدة من المفتاح الخاص. أنت مسؤول عن تخزينه بشكل آمن. إذا فقدت زوج المفاتيح هذا ، فستحتاج إلى إنشاء زوج جديد.

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

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

تفويض التفويض على مستوى النطاق لحساب الخدمة

إذا كان لديك حساب على Google Workspace، يمكن لمشرف المؤسسة تفويض تطبيق للوصول إلى بيانات المستخدمين نيابةً عن المستخدمين في نطاق Google Workspace. على سبيل المثال، قد يستخدم تطبيق يستخدم Google Calendar API لإضافة أحداث إلى تقاويم جميع المستخدمين في نطاق Google Workspace حساب خدمة للوصول إلى واجهة برمجة تطبيقات "تقويم Google" نيابةً عن المستخدمين. يُشار أحيانًا إلى تفويض حساب خدمة للوصول إلى البيانات بالنيابة عن المستخدمين في أحد النطاقات باسم "&&;تفويض التفويض على مستوى النطاق" بحساب خدمة.

لتفويض صلاحية على مستوى النطاق لحساب خدمة، على مشرف متميز لنطاق Google Workspace إكمال الخطوات التالية:

  1. من نطاقك على Google Workspace في "وحدة تحكُّم المشرف"، انتقِل إلى القائمة الرئيسية > Security > الوصول إلى البيانات والتحكُّم فيها &gt؛ عناصر تحكُّم واجهة برمجة التطبيقات.
  2. في لوحة التفويض على مستوى النطاق، اختَر إدارة التفويض على مستوى النطاق.
  3. انقر على إضافة نطاق جديد.
  4. في الحقل معرِّف العميل، أدخِل معرِّف العميل لحساب الخدمة. يمكنك العثور على معرِّف العميل لحساب الخدمة في Service accounts page.
  5. في الحقل نطاقات OAuth (مفصولة بفواصل)، أدخل قائمة النطاقات التي ينبغي منح تطبيقك إمكانية الوصول إليها. على سبيل المثال، إذا كان تطبيقك يحتاج إلى الوصول الكامل على مستوى النطاق إلى واجهة برمجة تطبيقات Google Drive وواجهة برمجة تطبيقات "تقويم Google"، أدخِل: https://www.googleapis.com/auth/drive، https://www.googleapis.com/auth/calendar.
  6. انقر على تفويض.

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

التحضير لإجراء طلب بيانات من واجهة برمجة التطبيقات المفوَّض

Java

بعد الحصول على عنوان البريد الإلكتروني للعميل والمفتاح الخاص من API Console، استخدِم مكتبة برامج Google APIs للغة Java لإنشاء عنصر GoogleCredential من بيانات اعتماد حساب الخدمة والنطاقات التي يحتاج التطبيق إلى الوصول إليها. مثلاً:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

إذا كنت بصدد تطوير تطبيق على Google Cloud Platform، يمكنك استخدام بيانات الاعتماد التلقائية للتطبيق بدلاً من ذلك، مما يسهّل عليك العملية.

تفويض التفويض على مستوى النطاق

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

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("user@example.com");

يمكنك استخدام الكائن GoogleCredential لاستدعاء واجهات Google API في تطبيقك.

Python

بعد الحصول على عنوان البريد الإلكتروني للعميل والمفتاح الخاص من API Console، يمكنك استخدام مكتبة برامج Google APIs للغة Python لإكمال الخطوات التالية:

  1. أنشئ كائن Credentials من بيانات اعتماد حساب الخدمة والنطاقات التي يحتاج التطبيق إلى الوصول إليها. على سبيل المثال:
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    إذا كنت بصدد تطوير تطبيق على Google Cloud Platform، يمكنك استخدام بيانات الاعتماد التلقائية للتطبيق بدلاً من ذلك، مما يسهّل عليك العملية.

  2. تفويض التفويض على مستوى النطاق

    إذا كنت قد فوضت إمكانية الوصول على مستوى النطاق إلى حساب الخدمة وتريد انتحال حساب مستخدم، استخدِم الطريقة with_subject لعنصر ServiceAccountCredentials حالي. مثلاً:

    delegated_credentials = credentials.with_subject('user@example.org')

استخدم كائن بيانات الاعتماد لاستدعاء Google APIs في تطبيقك.

HTTP/REST

بعد الحصول على معرّف العميل والمفتاح الخاص من API Console، يجب أن يكمل طلبك الخطوات التالية:

  1. يمكنك إنشاء رمز JSON المميّز للويب (JWT، طريقة اللفظ، "jot") والذي يحتوي على عنوان ومجموعة مطالبات وتوقيع.
  2. طلب رمز الدخول من خادم تفويض Google OAuth 2.0.
  3. يمكنك التعامل مع استجابة JSON التي يعرضها خادم المصادقة.

توضِّح الأقسام التالية كيفية إكمال هذه الخطوات.

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

عندما تنتهي صلاحية رمز الدخول، ينشئ تطبيقك رمز JWT آخر، ويوقّعه، ويطلب رمز دخول آخر.

يستخدم تطبيق الخادم رمز JWT لطلب رمز مميز من
                  خادم تفويض Google، ثم يستخدم الرمز المميز لطلب نقطة نهاية Google API. ولا يتم
 مشاركة أي مستخدم نهائي.

ويصف باقي هذا القسم تفاصيل إنشاء JWT وتوقيع JWT وإنشاء طلب رمز الدخول والتعامل مع الرد.

إنشاء JWT

يتكون JWT من ثلاثة أجزاء: العنوان ومجموعة الدعاوى والتوقيع. ويتكوّن العنوان ومجموعة الطلبات من كائنات JSON. ويتم إنشاء تسلسلات لعناصر JSON هذه باستخدام وحدات UTF-8 بايت، ثم ترميزها باستخدام ترميز Base64url. ويوفّر هذا الترميز مرونة في التعامل مع تغييرات الترميز بسبب عمليات الترميز المتكرّرة. يتم ربط العنوان ومجموعة المطالبة والتوقيع مع حرف النقطة (.).

يتم إنشاء JWT على النحو التالي:

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

السلسلة الأساسية للتوقيع كما يلي:

{Base64url encoded header}.{Base64url encoded claim set}
إنشاء عنوان JWT

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

تعتمد حسابات الخدمة على خوارزمية RSA SHA-256 وتنسيق الرمز المميّز JWT. ونتيجة لذلك، يكون تمثيل JSON للرأس على النحو التالي:

{"alg":"RS256","typ":"JWT"}

يظهر تمثيل Base64url كما يلي:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
تشكيل مجموعة JWT

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

المطالبات المطلوبة

يتم عرض المطالبات المطلوبة في مطالبة JWT أدناه. وقد تظهر بأي ترتيب في مجموعة المطالبات.

الاسم الوصف
iss عنوان البريد الإلكتروني لحساب الخدمة.
scope قائمة الأذونات المفصولة بطلب التطبيق والتي يتم الفصل بينها بمسافات.
aud واصف للهدف المقصود من التأكيد. عند إنشاء رمز دخول، ستكون هذه القيمة دائمًا https://oauth2.googleapis.com/token.
exp تمثّل هذه السمة وقت انتهاء صلاحية التأكيد، المحدّد بالثواني 00:00:00 بالتوقيت العالمي المُنسّق، 1 كانون الثاني (يناير) 1970. تكون هذه القيمة ساعة واحدة بعد الوقت المُحدَّد بحدٍ أقصى.
iat وقت إصدار التأكيد، المحدّد بالثواني 00:00:00 بالتوقيت العالمي المنسق (UTC)، 1 كانون الثاني (يناير) 1970.

يظهر أدناه تمثيل JSON للحقول المطلوبة في مجموعة مطالبات JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
مطالبات إضافية

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

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

الاسم الوصف
sub عنوان البريد الإلكتروني للمستخدم الذي يطلب التطبيق الدخول المفوَّض إليه.

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

نعرض أدناه مثالاً على مجموعة مطالبات JWT تتضمّن الحقل sub:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
ترميز مجموعة مطالبات JWT

وكما هي الحال في عنوان JWT، يجب أن يتم تحويل سلسلة إجراءات JWT إلى تنسيق UTF-8 وBase64url-safe. في ما يلي مثال على تمثيل JSON لمجموعة JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
احتساب التوقيع

توقيع الويب JSON (JWS) هو المواصفات التي توجه آليات إنشاء التوقيع لـ JWT. إدخال التوقيع هو مصفوفة وحدات البايت للمحتوى التالي:

{Base64url encoded header}.{Base64url encoded claim set}

يجب استخدام خوارزمية التوقيع في عنوان JWT عند احتساب التوقيع. خوارزمية التوقيع الوحيدة المتوافقة مع خادم تفويض Google OAuth 2.0 هي RSA باستخدام خوارزمية التجزئة SHA-256. ويُشار إلى ذلك باستخدام الحقل RS256 في الحقل alg في العنوان JWT.

وقِّع على تمثيل UTF-8 للإدخال باستخدام SHA256withRSA (المعروف أيضًا باسم RSASSA-PKCS1-V1_5-SIGN مع دالة التجزئة SHA-256) باستخدام المفتاح الخاص الذي تم الحصول عليه من Google API Console. ستكون النتيجة مصفوفة بايت.

يجب أن يكون التوقيع بترميز Base64url. يتم ربط العنوان ومجموعة المطالبة والتوقيع مع حرف النقطة (.). والنتيجة هي JWT. ويجب إضافة ما يلي (تتم إضافة فواصل الأسطر لتوضيح الأمر):

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

في ما يلي مثال على JWT قبل ترميز Base64url:

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

في ما يلي مثال على JWT تم توقيعها وجاهز للنقل:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

تقديم طلب رمز الدخول

بعد إنشاء رمز JWT المُوقَّع، يمكن للتطبيق استخدامه لطلب رمز الدخول. طلب رمز الدخول هذا هو طلب HTTPS POST، ويكون النص الأساسي مشفّرًا في عنوان URL. يظهر عنوان URL أدناه:

https://oauth2.googleapis.com/token

المعلمات التالية مطلوبة في طلب HTTPS POST:

الاسم الوصف
grant_type استخدِم السلسلة التالية، بترميز عنوان URL حسب الضرورة: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion رمز JWT، بما في ذلك التوقيع.

في ما يلي تفريغ أولي لطلب HTTPS POST المستخدَم في طلب رمز دخول:

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

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

في ما يلي الطلب نفسه باستخدام curl:

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

التعامل مع الاستجابة

إذا تم صياغة طلب JWT ورمز الدخول بشكل صحيح، وكان لحساب الخدمة إذن بإجراء العملية، تتضمن استجابة JSON من خادم التفويض رمز الدخول. في ما يلي مثال على الرد:

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

يمكن إعادة استخدام رموز الدخول خلال فترة المدة التي تحدّدها القيمة expires_in.

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

Java

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

  1. أنشئ كائن خدمة لواجهة برمجة التطبيقات التي تريد طلبها باستخدام العنصر GoogleCredential. على سبيل المثال:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. قدِّم طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام الواجهة التي يوفرها عنصر الخدمة. على سبيل المثال، لإدراج مثيلات قواعد بيانات Cloud SQL في مشروع Thriller-مثال-123:
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Python

استخدِم الكائن Credentials المفوَّض لاستدعاء واجهات Google API عن طريق اتّباع الخطوات التالية:

  1. أنشئ كائن خدمة لواجهة برمجة التطبيقات التي تريد طلبها. يمكنك إنشاء عنصر خدمة من خلال استدعاء الدالة build مع اسم واجهة برمجة التطبيقات وإصدارها وكائن Credentials المفوَّض. على سبيل المثال، لاستدعاء الإصدار 1تجريبي3 من Cloud SQL Management API:
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
  2. قدِّم طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام الواجهة التي يوفرها عنصر الخدمة. على سبيل المثال، لإدراج مثيلات قواعد بيانات Cloud SQL في مشروع Thriller-مثال-123:
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP/REST

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

ويمكنك تجربة جميع واجهات برمجة تطبيقات 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

عند انتهاء صلاحية رموز الدخول

تنتهي صلاحية رموز الدخول الصادرة عن خادم تفويض Google OAuth 2.0 بعد المدة المقدَّمة من قيمة expires_in. عند انتهاء صلاحية رمز الدخول، يجب أن ينشئ التطبيق رمز JWT آخر، وأن يوقّعه ويطلب رمز دخول آخر.

رموز خطأ JWT

حقل واحد (error) حقل واحد (error_description) المعنى كيفية الحل
unauthorized_client Unauthorized client or scope in request. إذا كنت تحاول استخدام تفويض على مستوى النطاق، فهذا يعني أن حساب الخدمة غير مصرح به في وحدة تحكم المشرف لنطاق المستخدم.

تأكّد من أن حساب الخدمة مفوّض في صفحة التفويض على مستوى النطاق ضمن "وحدة تحكُّم المشرف" للمستخدم في طلب sub في الحقل (حقل).

تستغرق عادةً عملية منح الإذن لجميع المستخدمين في حسابك على Google مدة تصل إلى بضع دقائق.

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. تم تفويض حساب الخدمة باستخدام عنوان البريد الإلكتروني للعميل بدلاً من معرِّف العميل (رقمي) في "وحدة تحكُّم المشرف". في صفحة التفويض على مستوى النطاق في وحدة تحكم المشرف، أزِل العميل وأعِد إضافته باستخدام المعرّف الرقمي.
access_denied (أي قيمة) إذا كنت تستخدم التفويض على مستوى النطاق، لا يُسمح باستخدام نطاق أو أكثر من النطاقات المطلوبة في "وحدة تحكُّم المشرف".

تأكّد من أن حساب الخدمة مفوّض في الصفحة التفويض على مستوى النطاق في "وحدة تحكّم المشرف" للمستخدم في المطالبة (الحقل) sub، ومن أنّه يتضمّن جميع النطاقات التي تطلبها في مطالبة scope باستخدام JWT.

تستغرق عادةً عملية منح الإذن لجميع المستخدمين في حسابك على Google مدة تصل إلى بضع دقائق.

invalid_grant Not a valid email. المستخدم غير موجود. تأكّد من أن عنوان البريد الإلكتروني في المطالبة (الحقل) sub صحيح.
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

وعادةً ما يعني ذلك أن توقيت النظام المحلي غير صحيح. ويمكن أن يحدث أيضًا إذا كانت قيمة exp أكبر من 65 دقيقة في المستقبل من القيمة iat، أو كانت قيمة exp أقل من قيمة iat.

تأكد من صحة الساعة التي تم فيها إنشاء JWT على النظام. إذا لزم الأمر، يمكنك مزامنة وقتك مع Google NTP.

invalid_grant Invalid JWT Signature.

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

وبدلاً من ذلك، قد يكون ترميز JWT مُشفَّرًا بشكل غير صحيح، حيث يجب أن يكون بترميز Base64 بدون أسطر جديدة أو علامات تساوي قيم المساحة المتروكة.

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

جرِّب استخدام مكتبة OAuth التي تقدمها Google للتأكد من إنشاء JWT بشكل صحيح.

invalid_scope Invalid OAuth scope or ID token audience provided. لم يتم طلب أي نطاقات (قائمة فارغة من النطاقات)، أو أن أحد النطاقات المطلوبة غير موجود (أي غير صالح).

تأكّد من ملء مطالبة scope (حقل) في JWT، وقارن النطاقات التي تتضمنها النطاقات الموثَّقة لواجهات برمجة التطبيقات التي تريد استخدامها، لضمان عدم وجود أخطاء أو أخطاء إملائية.

يجب فصل قائمة النطاقات في المطالبة scope بمسافات وليس فواصل.

disabled_client The OAuth client was disabled. تم إيقاف المفتاح المستخدَم للتوقيع على تأكيد JWT.

انتقِل إلى Google API Console، وضمن إدارة الهوية وإمكانية الوصول &amp؛ حسابات المشرف &gt؛ حسابات الخدمة، فعِّل حساب الخدمة الذي يحتوي على &quot؛معرّف المفتاح&;؛ المستخدم للتوقيع على التأكيد.

ملحق: تفويض حساب الخدمة بدون OAuth

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

إذا كانت واجهة برمجة التطبيقات التي تريد استدعاؤها تتضمن تعريف خدمة منشورًا في مستودع GitHub ضمن Google APIs، يمكنك إجراء طلبات بيانات من واجهة برمجة التطبيقات المفوَّضة باستخدام JWT بدلاً من رمز الدخول. ولإجراء ذلك، يُرجى اتّباع الخطوات التالية:

  1. أنشئ حساب خدمة كما هو موضّح أعلاه. لذلك، احرص على الاحتفاظ بملف JSON الذي تحصل عليه عند إنشاء الحساب.
  2. باستخدام أي مكتبة JWT عادية، مثل مكتبة jwt.io، يمكنك إنشاء JWT مع عنوان وحمولة مثل المثال التالي:
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • بالنسبة إلى الحقل kid في رأس الصفحة، حدِّد رقم تعريف المفتاح الخاص بحساب الخدمة. يمكنك العثور على هذه القيمة في الحقل private_key_id في ملف JSON لحساب الخدمة.
    • بالنسبة إلى الحقلين iss وsub، حدِّد عنوان البريد الإلكتروني الخاص بحساب الخدمة. يمكنك العثور على هذه القيمة في الحقل client_email في ملف JSON لحساب الخدمة.
    • بالنسبة إلى الحقل aud، حدِّد نقطة نهاية واجهة برمجة التطبيقات. مثلاً: https://SERVICE.googleapis.com/.
    • بالنسبة إلى الحقل iat، حدِّد وقت Unix الحالي، وبالنسبة إلى الحقل exp، حدِّد الوقت بالضبط بعد 3600 ثانية، وهو الوقت الذي ستنتهي فيه صلاحية JWT.

وقِّع JWT على RSA-256 باستخدام المفتاح الخاص الموجود في ملف JSON لحساب الخدمة.

مثلاً:

Java

باستخدام google-api-java-client java-jwt:

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

Python

باستخدام PyJWT:

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. يمكنك طلب البيانات من واجهة برمجة التطبيقات باستخدام رمز JWT الموقَّع على أنه الرمز المميز للحامل:
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com