يتيح نظام Google OAuth 2.0 التفاعلات بين الخوادم، مثل التفاعلات بين تطبيق ويب وإحدى خدمات Google. في هذه الحالة، تحتاج إلى حساب خدمة، وهو حساب يخص تطبيقك بدلاً من مستخدم نهائي فردي. يطلب تطبيقك من واجهات برمجة تطبيقات Google تنفيذ إجراءات بالنيابة عن حساب الخدمة، وبالتالي لا يشارك المستخدمون بشكل مباشر في هذه العملية. يُطلق على هذا السيناريو أحيانًا اسم "OAuth ذو الخطوتين" أو "2LO". (يشير المصطلح ذو الصلة "بروتوكول OAuth الثلاثي" إلى سيناريوهات يستدعي فيها تطبيقك Google APIs بالنيابة عن المستخدمين النهائيين، وفيها تكون موافقة المستخدم مطلوبة في بعض الأحيان).
عادةً، يستخدم التطبيق حساب خدمة عندما يستخدم واجهات Google API للعمل مع بياناته الخاصة بدلاً من بيانات المستخدم. على سبيل المثال، يستخدم تطبيق يستعين بخدمة Google Cloud Datastore لتخزين البيانات بشكل دائم حساب خدمة للمصادقة على طلباته إلى واجهة برمجة التطبيقات Google Cloud Datastore API.
يمكن لمشرفي نطاق Google Workspace أيضًا منح حسابات الخدمة إذنًا على مستوى النطاق للوصول إلى بيانات المستخدمين نيابةً عن المستخدمين في النطاق.
يوضّح هذا المستند كيف يمكن لأحد التطبيقات إكمال عملية OAuth 2.0 من الخادم إلى الخادم باستخدام إحدى مكتبات برامج Google APIs (يُنصح بذلك) أو HTTP.
نظرة عامة
لإتاحة التفاعلات بين الخادم والخادم، عليك أولاً إنشاء حساب خدمة لمشروعك في API Console. إذا كنت تريد الوصول إلى بيانات المستخدمين في حسابك على Google Workspace، عليك تفويض حساب الخدمة بالوصول إلى النطاق بالكامل.
بعد ذلك، يستعد تطبيقك لإجراء طلبات بيانات من واجهة برمجة التطبيقات مع إذن الوصول من خلال استخدام بيانات اعتماد حساب الخدمة لطلب رمز مميّز للوصول من خادم مصادقة OAuth 2.0.
أخيرًا، يمكن لتطبيقك استخدام رمز الدخول لطلب بيانات من واجهات Google API.
إنشاء حساب خدمة
تتضمّن بيانات اعتماد حساب الخدمة عنوان بريد إلكتروني تم إنشاؤه وهو فريد من نوعه وزوج مفاتيح عامة/خاصة واحد على الأقل. في حال تفعيل التفويض على مستوى النطاق، يكون معرّف العميل أيضًا جزءًا من بيانات اعتماد حساب الخدمة.
إذا كان تطبيقك يعمل على Google App Engine، يتم إعداد حساب خدمة تلقائيًا عند إنشاء مشروعك.
إذا كان تطبيقك يعمل على Google Compute Engine، يتم أيضًا إعداد حساب خدمة تلقائيًا عند إنشاء مشروعك، ولكن عليك تحديد النطاقات التي يحتاج تطبيقك إلى الوصول إليها عند إنشاء مثيل Google Compute Engine. لمزيد من المعلومات، يُرجى الاطّلاع على إعداد آلة افتراضية لاستخدام حسابات الخدمة.
إذا لم يكن تطبيقك يعمل على Google App Engine أو Google Compute Engine، عليك الحصول على بيانات الاعتماد هذه في Google API Console. لإنشاء بيانات اعتماد حساب الخدمة أو لعرض بيانات الاعتماد العامة التي سبق أن أنشأتها، اتّبِع الخطوات التالية:
First, create a service account:
- Open the Service accounts page.
- If prompted, select a project, or create a new one.
- Click Create service account.
- Under Service account details, type a name, ID, and description for the service account, then click Create and continue.
- Optional: Under Grant this service account access to project, select the IAM roles to grant to the service account.
- Click Continue.
- Optional: Under Grant users access to this service account, add the users or groups that are allowed to use and manage the service account.
- Click Done.
Next, create a service account key:
- Click the email address for the service account you created.
- Click the Keys tab.
- In the Add key drop-down list, select Create new key.
- Click Create.
Your new public/private key pair is generated and downloaded to your machine; it serves as the only copy of the private key. You are responsible for storing it securely. If you lose this key pair, you will need to generate a new one.
يمكنك الرجوع إلى 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 وواجهة برمجة تطبيقات "تقويم Google"، أدخِل: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
- انقر على تفويض.
يتمتع تطبيقك الآن بإذن إجراء طلبات إلى واجهة برمجة التطبيقات بصفتك مستخدمًا في نطاق Workspace (أي "انتحال" هوية المستخدمين). عند الاستعداد لإجراء طلبات البيانات من واجهة برمجة التطبيقات المفوَّضة هذه، عليك تحديد المستخدم الذي سيتم انتحال هويته بشكل صريح.
الاستعداد لإجراء طلب بيانات من واجهة برمجة التطبيقات مفوَّض
Java
بعد الحصول على عنوان البريد الإلكتروني للعميل والمفتاح الخاص من
API Console، استخدِم
مكتبة Google Auth Library للغة Java
لإنشاء عنصر GoogleCredentials
من بيانات اعتماد حساب الخدمة
ونطاقات الوصول التي يحتاجها تطبيقك. على سبيل المثال:
import com.google.auth.oauth2.GoogleCredentials; import com.google.api.services.sqladmin.SQLAdminScopes; // ... GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("MyProject-1234.json")) .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));
إذا كنت بصدد تطوير تطبيق على Google Cloud Platform، يمكنك استخدام بيانات الاعتماد التلقائية للتطبيق بدلاً من ذلك، ما قد يسهّل العملية.
تفويض السلطة على مستوى النطاق
إذا فوّضت حساب الخدمة بالوصول إلى النطاق بأكمله وأردت انتحال هوية حساب مستخدم، حدِّد عنوان البريد الإلكتروني لحساب المستخدم باستخدام طريقة createDelegated
لكائن GoogleCredentials
. على سبيل المثال:
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("MyProject-1234.json")) .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN)) .createDelegated("workspace-user@example.com");
يستخدم الرمز البرمجي أعلاه الكائن GoogleCredentials
لاستدعاء الطريقة 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 APIs في تطبيقك.
HTTP/REST
بعد الحصول على معرّف العميل والمفتاح الخاص من API Console، يجب أن يكمل تطبيقك الخطوات التالية:
- أنشئ رمز JSON مميّز للويب (JWT، ويُلفظ "جوت") يتضمّن عنوانًا ومجموعة طلبات وتوقيعًا.
- اطلب رمز دخول من خادم مصادقة Google OAuth 2.0.
- تعامَل مع استجابة JSON التي يعرضها خادم التفويض.
توضّح الأقسام التالية كيفية إكمال هذه الخطوات.
إذا تضمّنت الاستجابة رمز دخول، يمكنك استخدام رمز الدخول لاستدعاء إحدى واجهات برمجة التطبيقات من Google. (إذا لم يتضمّن الرد رمز دخول، قد لا يكون طلب 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
يتألف العنوان من ثلاثة حقول تشير إلى خوارزمية التوقيع وتنسيق البيان ومعرّف المفتاح الخاص بمفتاح حساب الخدمة الذي تم استخدامه لتوقيع رمز JWT. يجب تحديد الخوارزمية والتنسيق، ويحتوي كل حقل على قيمة واحدة فقط. ومع إضافة المزيد من الخوارزميات والتنسيقات، سيتغيّر هذا العنوان وفقًا لذلك. معرّف المفتاح اختياري، وفي حال تحديد معرّف مفتاح غير صحيح، ستحاول منصة GCP استخدام جميع المفاتيح المرتبطة بحساب الخدمة للتحقّق من الرمز المميز ورفضه في حال عدم العثور على مفتاح صالح. تحتفظ 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 بالتوقيت العالمي المتفق عليه، في 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
استخدِم العنصر GoogleCredentials
لطلب بيانات من Google APIs باتّباع الخطوات التالية:
- أنشئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها باستخدام العنصر
GoogleCredentials
. على سبيل المثال:SQLAdmin sqladmin = new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credentials).build();
- إرسال طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام
الواجهة التي يوفّرها عنصر الخدمة
على سبيل المثال، لإدراج مثيلات قواعد بيانات Cloud SQL في المشروع exciting-example-123، اتّبِع الخطوات التالية:
SQLAdmin.Instances.List instances = sqladmin.instances().list("exciting-example-123").execute();
Python
استخدِم العنصر Credentials
المفوَّض لاستدعاء واجهات Google API من خلال إكمال الخطوات التالية:
- أنشئ عنصر خدمة لواجهة برمجة التطبيقات التي تريد طلبها. يمكنك إنشاء عنصر خدمة
من خلال استدعاء الدالة
build
مع اسم واجهة برمجة التطبيقات وإصدارها وعنصرCredentials
المفوّض. على سبيل المثال، لطلب بيانات من الإصدار 1beta3 من Cloud SQL Administration API، استخدِم ما يلي:import googleapiclient.discovery sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
- إرسال طلبات إلى خدمة واجهة برمجة التطبيقات باستخدام
الواجهة التي يوفّرها عنصر الخدمة
على سبيل المثال، لإدراج مثيلات قواعد بيانات Cloud SQL في المشروع exciting-example-123، اتّبِع الخطوات التالية:
response = sqladmin.instances().list(project='exciting-example-123').execute()
HTTP/REST
بعد أن يحصل تطبيقك على رمز مميّز للوصول، يمكنك استخدام الرمز المميز لإجراء طلبات إلى إحدى واجهات برمجة التطبيقات من Google نيابةً عن حساب خدمة أو حساب مستخدم معيّنَين، وذلك إذا تم منح نطاقات الوصول التي تتطلّبها واجهة برمجة التطبيقات. لإجراء ذلك، يجب تضمين رمز الدخول في طلب إلى واجهة برمجة التطبيقات من خلال تضمين مَعلمة طلب بحث access_token
أو قيمة Bearer
في عنوان HTTP Authorization
. عند الإمكان، من الأفضل استخدام عنوان HTTP لأنّ سلاسل طلب البحث تكون عادةً مرئية في سجلات الخادم. في معظم الحالات، يمكنك استخدام مكتبة برامج العميل لإعداد طلباتك إلى واجهات Google API (على سبيل المثال، عند طلب Drive Files API).
يمكنك تجربة جميع واجهات Google APIs والاطّلاع على نطاقاتها في مساحة بروتوكول OAuth 2.0.
أمثلة على طلبات HTTP GET
قد يبدو طلب إلى نقطة النهاية
drive.files
(واجهة برمجة التطبيقات Drive Files API) باستخدام عنوان 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 المميّز صحيح وتم إصداره لمعرّف العميل في الطلب. |
deleted_client |
(أي قيمة) |
تم حذف عميل OAuth المستخدَم لتقديم الطلب. يمكن أن تتم عملية الحذف يدويًا أو تلقائيًا في حال عدم استخدام برامج . يمكن استعادة العملاء المحذوفين في غضون 30 يومًا من الحذف. مزيد من المعلومات |
استخدِم معرّف عميل لا يزال نشطًا. |
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 APIs إجراء طلبات معتمَدة إلى واجهة برمجة التطبيقات باستخدام رمز JWT موقَّع مباشرةً كرمز مميّز للحامل، بدلاً من رمز دخول OAuth 2.0. عندما يكون ذلك ممكنًا، يمكنك تجنُّب الحاجة إلى إرسال طلب شبكة إلى خادم التفويض التابع لـ Google قبل إجراء طلب إلى واجهة برمجة التطبيقات.
إذا كانت واجهة برمجة التطبيقات التي تريد طلب بيانات منها تتضمّن تعريف خدمة منشورًا في مستودع Google APIs على 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-auth-library-java و java-jwt:
import com.google.auth.oauth2.ServiceAccountCredentials; ... GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("MyProject-1234.json")); PrivateKey privateKey = ((ServiceAccountCredentials) credentials).getPrivateKey(); String privateKeyId = ((ServiceAccountCredentials) credentials).getPrivateKeyId(); 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
تفعيل ميزة "الحماية العابرة للحساب"
من الخطوات الإضافية التي يجب اتّخاذها لحماية حسابات المستخدمين تنفيذ ميزة "الحماية على مستوى الحسابات" من خلال الاستفادة من خدمة "الحماية على مستوى الحسابات" من Google. تتيح لك هذه الخدمة الاشتراك في تلقّي إشعارات بشأن أحداث الأمان التي تقدّم معلومات لتطبيقك حول التغييرات الرئيسية التي تطرأ على حساب المستخدم. يمكنك بعد ذلك استخدام المعلومات لاتّخاذ إجراءات استنادًا إلى طريقة الردّ على الأحداث.
في ما يلي بعض الأمثلة على أنواع الأحداث التي ترسلها خدمة "الحماية على مستوى الحسابات" من Google إلى تطبيقك:
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
-
https://schemas.openid.net/secevent/oauth/event-type/token-revoked
-
https://schemas.openid.net/secevent/risc/event-type/account-disabled
يمكنك الاطّلاع على صفحة حماية حسابات المستخدمين باستخدام ميزة "الحماية العابرة للحساب" للحصول على مزيد من المعلومات حول كيفية تنفيذ ميزة "الحماية العابرة للحساب" والقائمة الكاملة بالأحداث المتاحة.