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

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
ولمزيد من المعلومات، يُرجى الاطّلاع على نظرة عامة على المصادقة في مستندات Google Cloud Platform.

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

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

ويمكن لمشرفي نطاق 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 Calendar API نيابةً عن المستخدمين. إنّ تفويض حساب خدمة للوصول إلى البيانات بالنيابة عن مستخدمين في نطاق معيّن يُشار إليه أحيانًا باسم "&تفويض تفويض على مستوى النطاق" لحساب خدمة.

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

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

يملك تطبيقك الآن صلاحية إجراء طلبات بيانات من واجهة برمجة التطبيقات كمستخدمين في نطاقك (للمستخدمين "im;"ate" المستخدمين). عند الاستعداد لإجراء طلبات بيانات من واجهة برمجة التطبيقات المسموح بها، يمكنك تحديد انتحال هوية المستخدم.

جارٍ الإعداد لإجراء استدعاء معتمد لواجهة برمجة التطبيقات

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 في تطبيقك.

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 بالتوقيت العالمي المُنسّق، 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 الموقَّع، يمكن للتطبيق استخدامه لطلب رمز الدخول. طلب الرمز المميّز للدخول هذا هو طلب POST باستخدام بروتوكول HTTPS، ويكون النص مشفّرًا بعنوان 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 APIs

Java

استخدِم الكائن GoogleCredential لاستدعاء واجهات Google API من خلال إكمال الخطوات التالية:

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

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

أمثلة على 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 (حقل).

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

على الرغم من أن هذا التفويض عادةً ما يستغرق بضع دقائق، ما يصل إلى 24 ساعة للوصول إلى جميع المستخدمين في حسابك على 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، وضمن IAM & Admin > حسابات الخدمة، فعِّل حساب الخدمة الذي يحتوي على "رقم تعريف المفتاح&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