يتوافق نظام Google OAuth 2.0 مع التفاعلات من خادم إلى خادم، مثل التفاعلات بين تطبيق ويب وخدمة من خدمات Google. بالنسبة إلى هذا السيناريو، تحتاج إلى حساب خدمة، وهو حساب ينتمي إلى طلبك بدلاً من مستخدم فردي. يستدعي التطبيق "واجهات برمجة تطبيقات Google" نيابةً عن حساب الخدمة، وبالتالي لا يشارك المستخدمون المستخدمين مباشرةً. يُسمى هذا السيناريو أحيانًا "بروتوكول OAuth الثنائي" أو "2LO". (يشير مصطلح "بروتوكول OAuth الثلاثي" إلى سيناريوهات يطلب فيها تطبيقك واجهات Google APIs نيابةً عن المستخدمين النهائيين، وتتطلب موافقة المستخدم أحيانًا).
عادةً ما يستخدم التطبيق حساب خدمة عندما يستخدم التطبيق واجهات Google APIs للعمل مع بياناته الخاصة بدلاً من بيانات المستخدم. على سبيل المثال، إذا كان هناك تطبيق يستخدم Google Cloud Datastore للاحتفاظ بالبيانات، سيتم استخدام حساب خدمة لمصادقة طلبات البيانات من خلال Google Cloud Datastore API.
ويمكن لمشرفي نطاق Google Workspace أيضًا منح أذونات على مستوى خدمة الخدمة للوصول إلى بيانات المستخدمين نيابةً عن المستخدمين في النطاق.
يوضّح هذا المستند طريقة نجاح التطبيق في إكمال المسار OAuth 2.0 من خادم إلى خادم، وذلك باستخدام مكتبة برامج Google APIs (إجراء مقترَح) أو بروتوكول HTTP.
نظرة عامة
لإتاحة التفاعلات من خادم إلى خادم، عليك أولاً إنشاء حساب خدمة لمشروعك في API Console. وإذا كنت تريد الوصول إلى بيانات المستخدمين للمستخدمين في حسابك على Google Workspace، يمكنك تفويض الوصول على مستوى النطاق إلى حساب الخدمة.
بعد ذلك، يتم تحضير تطبيقك لإجراء طلبات بيانات من واجهة برمجة التطبيقات المصرّح بها باستخدام بيانات اعتماد حساب الخدمة لطلب رمز الدخول من خادم المصادقة OAuth 2.0.
أخيرًا، يمكن للتطبيق استخدام رمز الدخول للاتصال بواجهات برمجة تطبيقات Google.
إنشاء حساب خدمة
تشمل بيانات اعتماد حساب الخدمة عنوان بريد إلكتروني مُنشأ فريدًا وزوج واحد على الأقل من مفاتيح التشفير العلنية أو الخاصة. في حال تفعيل التفويض على مستوى النطاق، يصبح معرِّف العميل جزءًا أيضًا من بيانات اعتماد حساب الخدمة.
إذا كان تطبيقك يعمل على Google App Engine، سيتم إعداد حساب خدمة تلقائيًا عند إنشاء مشروعك.
إذا تم تشغيل تطبيقك على Google Compute Engine، يتم أيضًا إعداد حساب خدمة تلقائيًا عند إنشاء مشروعك، ولكن عليك تحديد النطاقات التي يحتاج تطبيقك إلى الوصول إليها عند إنشاء مثيل Google Compute Engine. ولمزيد من المعلومات، يُرجى الاطّلاع على إعداد مثيل لاستخدام حسابات الخدمة.
إذا لم يتم تشغيل تطبيقك على Google App Engine أو Google Compute Engine، يجب الحصول على بيانات الاعتماد هذه في Google API Console. لإنشاء بيانات اعتماد حساب الخدمة أو لعرض بيانات الاعتماد العلنية التي أنشأتها سابقًا، يُرجى تنفيذ ما يلي:
أولاً ، قم بإنشاء حساب خدمة:
- افتح Service accounts page.
- If prompted, select a project, or create a new one.
- انقر فوق إنشاء حساب الخدمة .
- ضمن تفاصيل حساب الخدمة ، اكتب اسمًا ومعرفًا ووصفًا لحساب الخدمة ، ثم انقر فوق إنشاء ومتابعة .
- اختياري: ضمن منح حق الوصول إلى حساب الخدمة هذا للمشروع ، حدد أدوار IAM لمنح حساب الخدمة.
- انقر فوق متابعة .
- اختياري: ضمن منح المستخدمين حق الوصول إلى حساب الخدمة هذا ، أضف المستخدمين أو المجموعات المسموح لها باستخدام حساب الخدمة وإدارته.
- انقر فوق تم .
بعد ذلك ، قم بإنشاء مفتاح حساب الخدمة:
- انقر فوق عنوان البريد الإلكتروني لحساب الخدمة الذي أنشأته.
- انقر فوق علامة التبويب المفاتيح .
- في القائمة المنسدلة إضافة مفتاح ، حدد إنشاء مفتاح جديد .
- انقر فوق إنشاء .
يتم إنشاء زوج المفاتيح العام / الخاص الجديد وتنزيله على جهازك ؛ إنه بمثابة النسخة الوحيدة من المفتاح الخاص. أنت مسؤول عن تخزينه بشكل آمن. إذا فقدت زوج المفاتيح هذا ، فستحتاج إلى إنشاء زوج جديد.
يمكنك الرجوع إلى API Console في أي وقت لعرض عنوان البريد الإلكتروني وبصمات أصابع المفتاح العامة ومعلومات أخرى، أو إنشاء أزواج مفاتيح عامة أو خاصة إضافية. لمزيد من التفاصيل حول بيانات اعتماد حساب الخدمة في API Console، راجِع حسابات الخدمة في ملف مساعدة API Console.
دوِّن عنوان البريد الإلكتروني لحساب الخدمة واحفظ ملف المفتاح الخاص بحساب الخدمة في موقع جغرافي يسهُل الوصول إليه. ويلزمك التطبيق لإجراء طلبات بيانات من واجهة برمجة التطبيقات المصرّح بها.
تفويض تفويض على مستوى النطاق لحساب الخدمة
باستخدام حساب Google Workspace، يمكن لمشرف Workspace في المؤسسة تفويض تطبيق للوصول إلى بيانات المستخدمين في Workspace نيابةً عن المستخدمين في نطاق Google Workspace. على سبيل المثال، عند استخدام تطبيق يستخدم Google Calendar API لإضافة أحداث إلى تقاويم جميع المستخدمين في نطاق Google Workspace، يتم استخدام حساب خدمة للوصول إلى Google Calendar API نيابةً عن المستخدمين. يُشار أحيانًا إلى تفويض حساب خدمة بالوصول إلى البيانات نيابة عن المستخدمين في أحد النطاقات باسم "تفويض تفويض على مستوى النطاق" بحساب خدمة.
لتفويض تفويض على مستوى النطاق إلى حساب خدمة، على مشرف متميّز على نطاق Google Workspace إكمال الخطوات التالية:
- من وحدة تحكّم المشرف في نطاق Google Workspace، انتقِل إلى القائمة الرئيسية > الأمان > التحكّم في الوصول والبيانات > عناصر تحكّم واجهة برمجة التطبيقات.
- في لوحة التفويض على مستوى النطاق، اختَر إدارة التفويض على مستوى النطاق.
- انقر على إضافة جديد.
- في الحقل معرِّف العميل، أدخِل معرِّف العميل لحساب الخدمة. يمكنك العثور على معرِّف عميل حساب الخدمة الخاص بك في Service accounts page.
- في الحقل نطاقات OAuth (مفصولة بفواصل)، أدخِل قائمة النطاقات التي يجب منح تطبيقك الإذن بالوصول إليها. على سبيل المثال، إذا كان تطبيقك بحاجة إلى الوصول الكامل على مستوى النطاق إلى Google Drive API وGoogle Calendar API، أدخِل: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
- انقر على تفويض.
يملك تطبيقك الآن تفويضًا لإجراء طلبات بيانات من واجهة برمجة التطبيقات كمستخدمين في نطاق Workspace (لـ "انتحال هوية المستخدمين"). وعند الاستعداد لإجراء طلبات البيانات هذه من واجهة برمجة التطبيقات المفوَّضة، ستحدِّد بشكلٍ صريح للمستخدم أن ينتحل هويته.
جارٍ التحضير لإجراء طلب بيانات من واجهة برمجة التطبيقات المفوَّض
لغة 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("workspace-user@example.com");
يستخدِم الرمز أعلاه الكائن GoogleCredential
لاستدعاء الطريقة createDelegated()
. يجب أن تكون الوسيطة للطريقة createDelegated()
مستخدمًا ينتمي إلى
حسابك على Workspace. سيستخدم الرمز الذي يقدّم الطلب بيانات الاعتماد هذه لاستدعاء واجهات برمجة تطبيقات Google باستخدام حساب الخدمة الخاص بك.
لغة Python
بعد الحصول على عنوان البريد الإلكتروني للعميل والمفتاح الخاص من API Console، استخدِم مكتبة برامج Google APIs للغة Python لإكمال الخطوات التالية:
- إنشاء كائن
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، يمكنك استخدام بيانات الاعتماد التلقائية للتطبيق بدلاً من ذلك، ما يسهّل العملية.
- تفويض تفويض على مستوى النطاق
إذا منحت إذنًا بالوصول على مستوى النطاق إلى حساب الخدمة وأردت انتحال هوية حساب مستخدم، استخدِم الإجراء
with_subject
لكائنServiceAccountCredentials
الحالي. على سبيل المثال:delegated_credentials = credentials.with_subject('user@example.org')
استخدام كائن "بيانات الاعتماد" لاستدعاء واجهات Google API في تطبيقك
HTTP/REST
بعد الحصول على معرِّف العميل والمفتاح الخاص من API Console، يجب أن يكمل طلبك الخطوات التالية:
- أنشِئ رمزًا مميّزًا لـ JSON على الويب (JWT)، ولفظه مثل "jot" يتضمّن عنوانًا ومجموعة مطالبات وتوقيعًا.
- اطلب رمز الدخول من خادم مصادقة Google OAuth 2.0.
- التعامل مع استجابة JSON التي يعرضها خادم التفويض
توضّح الأقسام التالية طريقة إكمال هذه الخطوات.
إذا كانت الاستجابة تشمل رمز الدخول، يمكنك استخدام رمز الدخول للاستدعاء بواجهة برمجة تطبيقات Google. (إذا لم تتضمّن الاستجابة رمزًا مميزًا للوصول، قد يكون تنسيق طلب JWT والرمز المميّز غير صحيح، أو قد لا يكون لحساب الخدمة إذن بالوصول إلى النطاقات المطلوبة).
عند انتهاء صلاحية رمز الدخول، ينشئ تطبيقك رمز JWT آخر ويوقِّعه ويطلب رمز دخول آخر.

توضّح باقي هذا القسم تفاصيل إنشاء 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
يتألف العنوان من ثلاثة حقول تشير إلى خوارزمية التوقيع وتنسيق التأكيد و[رقم التعريف الأساسي لمفتاح حساب الخدمة](https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys) الذي تم استخدامه لتوقيع JWT. إنّ الخوارزمية والتنسيق إلزاميان، ولكل حقل قيمة واحدة فقط. ومع تقديم خوارزميات وتنسيقات إضافية، سيتغيّر هذا العنوان وفقًا لذلك. معرّف المفتاح اختياري، وإذا تم تحديد رقم تعريف مفتاح غير صحيح، ستحاول خدمة Google Cloud Platform كل المفاتيح المرتبطة بحساب الخدمة للتحقّق من الرمز المميّز ورفض الرمز المميّز في حال عدم العثور على أي مفتاح صالح. وتحتفظ Google بالحق في رفض الرموز المميّزة التي تتضمّن أرقام تعريف مفاتيح غير صحيحة في المستقبل.
تعتمد حسابات الخدمة على خوارزمية RSA SHA-256 وتنسيق الرمز المميّز JWT. ونتيجةً لذلك، يكون تمثيل JSON للرأس على النحو التالي:
{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}
في ما يلي تمثيل Base64url كما يلي:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
تشكيل مجموعة المطالبات باستخدام JWT
تتضمّن مجموعة JWT معلومات حول JWT، بما في ذلك الأذونات المطلوبة (النطاقات) والهدف من الرمز المميّز وجهة الإصدار ووقت إصدار الرمز المميّز وفترة صلاحية الرمز المميّز. معظم الحقول إلزامية، وكما هي الحال في عنوان JWT، تكون مجموعة المطالبات JWT عبارة عن عنصر JSON ويتم استخدامها في احتساب التوقيع.
المطالبات المطلوبة
تظهر أدناه المطالبات المطلوبة في مجموعة مطالبات JWT. ويمكن أن تظهر الإعلانات بأي ترتيب في مجموعة المطالبات.
الاسم | الوصف |
---|---|
iss |
عنوان البريد الإلكتروني لحساب الخدمة. |
scope |
قائمة بالأذونات المُحدَّدة بمسافات التي يطلبها التطبيق. |
aud |
تمثّل هذه السمة وصفًا للهدف المقصود من التأكيد. عند إنشاء رمز دخول،
يجب طلب هذه القيمة دائمًا https://oauth2.googleapis.com/token . |
exp |
تمثّل هذه السمة وقت انتهاء الصلاحية الذي يتم تحديده كثوانٍ منذ 00:00:00 حسب التوقيت العالمي المنسَّق (UTC)، 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 هو المواصفات التي توجّه آليات إنشاء التوقيع إلى 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
لغة Java
استخدِم الكائن GoogleCredential
لاستدعاء واجهات Google API من خلال إكمال
الخطوات التالية:
- أنشِئ عنصر خدمة لواجهة برمجة التطبيقات تريد طلبه باستخدام العنصر
GoogleCredential
. على سبيل المثال:SQLAdmin sqladmin = new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
- تقديم طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام الواجهة التي يقدمها عنصر الخدمة
على سبيل المثال، لسرد مثيلات قواعد بيانات Cloud SQL في مشروع Thriller-123
:
SQLAdmin.Instances.List instances = sqladmin.instances().list("exciting-example-123").execute();
لغة Python
استخدِم عنصر Credentials
المفوَّض لاستدعاء واجهات Google API من خلال إكمال الخطوات التالية:
- أنشئ كائن خدمة لواجهة برمجة التطبيقات التي تريد طلبها. يمكنك إنشاء عنصر خدمة من خلال طلب الدالة
build
مع اسم واجهة برمجة التطبيقات وإصدارها وعنصرCredentials
المفوَّض. على سبيل المثال، لاستدعاء الإصدار 1 (الإصدار التجريبي) 3 من Cloud SQL Management API:import googleapiclient.discovery sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
- تقديم طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام الواجهة التي يقدمها عنصر الخدمة
على سبيل المثال، لسرد مثيلات قواعد بيانات 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 Files API).
يمكنك تجربة جميع واجهات Google API والاطّلاع على نطاقاتها في مساحة بروتوكول 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. |
إذا كنت تحاول استخدام التفويض على مستوى النطاق، لن يتم تفويض حساب الخدمة في "وحدة تحكُّم المشرف" لنطاق المستخدم. |
تأكَّد من تفويض حساب الخدمة في
التفويض على مستوى النطاق في وحدة تحكّم المشرف للمستخدم في
المطالبة (حقل) في حين أنّ نشر الإذن في حسابات جميع المستخدمين في حسابك على Google قد يستغرق عادةً بضع دقائق، قد يستغرق الأمر مدة تصل إلى 24 ساعة. |
unauthorized_client |
Client is unauthorized to retrieve access tokens using this method, or client not
authorized for any of the scopes requested. |
تم تفويض حساب خدمة باستخدام عنوان البريد الإلكتروني للعميل بدلاً من معرِّف العميل (رقمي) في وحدة تحكُّم المشرف. | في صفحة التفويض على مستوى النطاق في وحدة تحكّم المشرف، أزِل العميل وأعِد إضافته باستخدام المعرّف الرقمي. |
access_denied |
(أي قيمة) | إذا كنت تستخدم التفويض على مستوى النطاق، لن يتم تفويض نطاق واحد أو أكثر من النطاقات المطلوبة في "وحدة تحكُّم المشرف". |
تأكّد من أنّ حساب الخدمة مفوّض في صفحة
التفويض على مستوى النطاق في "وحدة تحكّم المشرف" للمستخدم في
المطالبة في حين أنّ نشر الإذن في حسابات جميع المستخدمين في حسابك على Google قد يستغرق عادةً بضع دقائق، قد يستغرق الأمر مدة تصل إلى 24 ساعة. |
admin_policy_enforced |
(أي قيمة) | يتعذّر على حساب Google تفويض نطاق واحد أو أكثر مطلوب بسبب سياسات مشرف Google Workspace. |
يُرجى الاطّلاع على مقالة مساعدة مشرف Google Workspace التحكُّم في اختيار التطبيقات التابعة لجهات خارجية والتطبيقات الداخلية التي يمكنها الوصول إلى بيانات Google Workspace للتعرُّف على المزيد من المعلومات حول كيفية تقييد المشرف لإذن الوصول إلى جميع النطاقات أو النطاقات الحساسة والمشروطة إلى أن يتم منح إمكانية الوصول صراحةً إلى معرِّف عميل OAuth. |
invalid_client |
(أي قيمة) |
عميل OAuth أو الرمز المميّز لـ JWT غير صالح أو تم ضبطه بشكل غير صحيح. يمكنك الرجوع إلى وصف الخطأ للحصول على التفاصيل. |
تأكّد من أنّ الرمز المميّز JWT صالح ويحتوي على مطالبات صحيحة. تأكّد من ضبط حساب عميل OAuth وحساب الخدمة بشكلٍ صحيح ومن استخدام عنوان البريد الإلكتروني الصحيح. تحقَّق من أنّ الرمز المميّز JWT صحيح وتم إصداره لمعرِّف العميل في الطلب. |
invalid_grant |
Not a valid email. |
المستخدم غير موجود. | تأكّد من صحة عنوان البريد الإلكتروني الوارد في المطالبة sub (الحقل). |
invalid_grant |
|
ويعني ذلك عادةً أنّ وقت النظام المحلي غير صحيح. ويمكن أن يحدث ذلك أيضًا إذا كانت قيمة
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. |
لم يتم طلب أي نطاقات (قائمة فارغة من النطاقات)، أو أن أحد النطاقات المطلوبة غير متوفّر (أي غير صالح). |
تأكّد من تعبئة المطالبة يُرجى العلم أنّه يجب الفصل بين قائمة النطاقات في المطالبة |
disabled_client |
The OAuth client was disabled. |
تم إيقاف المفتاح المستخدَم للتوقيع على تأكيد JWT. |
انتقِل إلى Google API Consoleوضمن إدارة الهوية وإمكانية الوصول والمشرف > حسابات الخدمة، فعِّل حساب الخدمة الذي يحتوي على "رقم تعريف المفتاح" المُستخدَم لتوقيع التأكيد. |
org_internal |
This client is restricted to users within its organization. |
معرّف عميل OAuth في الطلب هو جزء من مشروع يحدّ من إمكانية الوصول إلى حسابات Google في مؤسسة Google Cloud محددة. |
استخدم حساب خدمة من المؤسسة للمصادقة. أكِّد إعدادات نوع المستخدم لتطبيق OAuth. |
الملحق: تفويض حساب الخدمة بدون بروتوكول OAuth
باستخدام بعض واجهات Google API، يمكنك إجراء طلبات بيانات من واجهة برمجة التطبيقات المصرّح بها باستخدام رمز JWT موقَّع مباشرةً كرمز مميز للحامل، بدلاً من رمز دخول OAuth 2.0. وعندما يكون ذلك ممكنًا، يمكنك تجنُّب تقديم طلب عبر شبكة إلى خادم تفويض Google قبل طلب بيانات من واجهة برمجة التطبيقات.
إذا كانت واجهة برمجة التطبيقات التي تريد طلبها تتضمّن تعريف خدمة منشورًا في مستودع GitHub في Google GitHub، يمكنك إجراء طلبات بيانات من واجهة برمجة التطبيقات المصرّح بها باستخدام JWT بدلاً من رمز الدخول. ولإجراء ذلك، يُرجى اتّباع الخطوات التالية:
- أنشئ حساب خدمة كما هو موضّح أعلاه. احرص على الاحتفاظ بملف JSON الذي تحصل عليه عند إنشاء الحساب.
- باستخدام أي مكتبة 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')
- يمكنك طلب بيانات من واجهة برمجة التطبيقات باستخدام رمز JWT الموقَّع كرمز مميّز للحامل:
GET /v1/projects/abc/databases/123/indexes HTTP/1.1 Authorization: Bearer SIGNED_JWT Host: firestore.googleapis.com