تلتزم Google بتعزيز المساواة العرقية في المجتمعات السوداء. أنظر كيف.

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

يدعم نظام 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.

ملخص

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

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

أخيرًا ، يمكن لتطبيقك استخدام رمز الوصول للاتصال بواجهات برمجة تطبيقات Google.

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

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

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

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

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

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

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

إذا كنت بحاجة إلى منح سلطة G Suite على مستوى النطاق لحساب الخدمة ، فانقر على عنوان البريد الإلكتروني لحساب الخدمة الذي أنشأته ، ثم انسخ القيمة من مربع المعرّف الفريد .

لتفويض السلطة لحساب الخدمة ، استخدم القيمة التي نسختها كمعرف العميل.

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

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

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

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

لتفويض سلطة على مستوى المجال لحساب خدمة ، قم أولاً بتمكين التفويض على مستوى المجال لحساب خدمة موجود في Service accounts page أو قم بإنشاء حساب خدمة جديد مع تمكين التفويض على مستوى المجال.

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

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

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

الاستعداد لإجراء مكالمة API معتمدة

جافا

بعد حصولك على عنوان البريد الإلكتروني للعميل والمفتاح الخاص من API Console ، استخدم مكتبة عميل Google APIs لجافا لإنشاء كائن 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 APIs في تطبيقك.

بايثون

بعد حصولك على عنوان البريد الإلكتروني للعميل والمفتاح الخاص من API Console ، استخدم مكتبة Google APIs Client Library for 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 الأسلوب with_subject لكائن ServiceAccountCredentials الموجود. على سبيل المثال:

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

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

HTTP / REST

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

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

تصف الأقسام التالية كيفية إتمام هذه الخطوات.

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

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

يستخدم تطبيق الخادم الخاص بك JWT لطلب رمز مميز من Google Authorization Server ، ثم يستخدم الرمز المميز لاستدعاء نقطة نهاية 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 Web Signature (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 APIs

جافا

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

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

بايثون

استخدم كائن Credentials المصرح به للاتصال بواجهات برمجة تطبيقات Google من خلال إكمال الخطوات التالية:

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

HTTP / REST

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

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

أمثلة HTTP GET

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

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> Service Accounts ، قم بتمكين حساب الخدمة الذي يحتوي على "معرّف المفتاح" المستخدم لتوقيع التأكيد.

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

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

إذا كان لواجهة برمجة التطبيقات التي تريد الاتصال بها تعريف خدمة منشور في مستودع Google APIs GitHub ، فيمكنك إجراء مكالمات API مصرح بها باستخدام 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 ، حدد نقطة نهاية API. على سبيل المثال: https:// SERVICE .googleapis.com/ .
    • بالنسبة إلى حقل iat ، حدد وقت Unix الحالي ، وبالنسبة لحقل exp ، حدد الوقت بالضبط بعد 3600 ثانية ، عندما تنتهي صلاحية JWT.

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

على سبيل المثال:

جافا

باستخدام 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 ...

بايثون

باستخدام 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