نقل البيانات إلى Google Identity Services

نظرة عامة

للحصول على رمز دخول لكل مستخدم من أجل طلب Google APIs، توفر Google واجهات برمجة تطبيقات متعددة مكتبات JavaScript:

يوفّر هذا الدليل تعليمات حول كيفية الانتقال من هذه المكتبات إلى منصة مكتبة "خدمات الهوية":

باتباع هذا الدليل، سوف:

  • استبدال مكتبة المنصة المتوقّفة نهائيًا بمكتبة "خدمات الهوية" أو
  • في حال استخدام مكتبة برامج واجهة برمجة التطبيقات، إزالة وحدة gapi.auth2 المتوقّفة نهائيًا أساليبه وكائناته، واستبدالها بأخرى مكافئة في "خدمات الهوية".

للحصول على وصف للتغييرات التي طرأت على JavaScript في "خدمات الهوية" مكتبة النظرة العامة وكيفية عمل تفويض المستخدم لمراجعة المصطلحات والمفاهيم الرئيسية.

إذا كنت تبحث عن مصادقة لتسجيل اشتراك المستخدم وتسجيل دخوله، فانظر بدلاً من ذلك، يمكنك نقل البيانات من خلال "تسجيل الدخول بحساب Google".

تحديد مسار التفويض

هناك مساران محتملان لتفويض المستخدم: المسار الضمني والترخيص. الرمز.

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

مؤشرات أن تطبيق الويب يستخدم المسار الضمني:

  • يعتمد تطبيق الويب الخاص بك على المتصفح فقط، وليس لديه نظام أساسي للخلفية.
  • يجب أن يكون المستخدم متاحًا لاستدعاء Google APIs، علمًا بأنّ تطبيقك لا يستخدم سوى إذن الوصول ولا تتطلب رموزًا مميزة للتحديث.
  • يحمّل تطبيق الويب apis.google.com/js/api.js.
  • يعتمد التنفيذ على OAuth 2.0 للويب من جهة العميل التطبيقات:
  • يستخدم تطبيقك الوحدات gapi.client أو gapi.auth2 المتوفّرة في. مكتبة برامج Google API للغة JavaScript

مؤشرات أن تطبيق الويب يستخدم تدفق رمز التفويض:

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

اختيار مسار التفويض

قبل البدء بالترحيل، يجب تحديد ما إذا كانت المتابعة مع التدفق الحالي أو اعتماد تدفق مختلف يلبي احتياجاتك على أفضل وجه.

راجِع اختيار مسار التفويض للتعرّف على الاختلافات الرئيسية. والمفاضلات بين المسارين.

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

يمكنك اختيار مسار التفويض باستخدام أدوات الاختيار أدناه.

التدفق الضمني

الحصول على رمز دخول للاستخدام داخل المتصفح أثناء تواجد المستخدم.

تعرض أمثلة التدفق الضمني تطبيقات الويب قبل نقل البيانات إلى وبعده. خدمات الهوية.

مسار رمز التفويض

يتم تسليم رمز تفويض تصدره Google لكل مستخدم إلى خادمك الخلفي. حيث يتم استبدالها برمز الدخول ورمز التحديث.

تعرض أمثلة تدفق رمز التفويض تطبيقات الويب قبل وبعد والنقل إلى خدمات الهوية.

في هذا الدليل، اتّبع التعليمات الواردة بالخط الغامق إضافة، إزالة أو تحديث أو استبدال وظيفة حالية.

التغييرات التي تطرأ على تطبيق الويب داخل المتصفح

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

تحديد الرمز البرمجي المتأثر والاختبار

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

في التطبيقات الكبيرة أو المعقّدة، قد يكون من الصعب العثور على جميع الرموز البرمجية المتأثرة إيقاف الوحدة gapi.auth2 نهائيًا. لتسجيل الاستخدام الحالي لـ قريبًا سيكون بوظيفة متوقفة نهائيًا على وحدة التحكم، يمكنك تعيين قيمة ملف تعريف الارتباط G_AUTH2_MIGRATION لـ informational. يمكنك اختياريًا إضافة نقطتين متبوعتين بقيمة رئيسية لتسجيل الدخول أيضًا إلى تخزين الجلسة. بعد تسجيل الدخول واستلام مراجعة بيانات الاعتماد أو إرسال السجلّات التي تم جمعها إلى الواجهة الخلفية للاطّلاع عليها لاحقًا التحليل. على سبيل المثال، يحفظ informational:showauth2use المصدر وعنوان URL في مفتاح تخزين الجلسة باسم showauth2use.

للتحقّق من سلوك التطبيق عندما يتوقّف تحميل وحدة gapi.auth2، يمكنك ضبط قيمة ملف تعريف الارتباط G_AUTH2_MIGRATION إلى enforced. وهذا يمكّن من اختبار سلوك ما بعد الإيقاف النهائي لـ Google قبل تاريخ التنفيذ.

القيم المحتملة لملفات تعريف الارتباط G_AUTH2_MIGRATION:

  • enforced عدم تحميل وحدة gapi.auth2.
  • informational تسجيل استخدام الوظائف المتوقّفة نهائيًا في وحدة تحكّم JavaScript تسجيل الدخول أيضًا على تخزين الجلسة عند تحديد اسم مفتاح اختياري: informational:key-name

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

المكتبات والوحدات

تدير الوحدة gapi.auth2 مصادقة المستخدم لتسجيل الدخول وعملية المصادقة الضمنية. للحصول على إذن، فاستبدل هذه الوحدة المتوقّفة نهائيًا والكائنات مع مكتبة خدمات هوية Google.

إضافة مكتبة "خدمات الهوية" إلى تطبيق الويب من خلال تضمينها في المستند:

<script src="https://accounts.google.com/gsi/client" async defer></script>

أزِل أي حالات تحميل لوحدة auth2 باستخدام gapi.load('auth2', function).

تحلّ مكتبة "خدمات هوية Google" محلّ استخدام وحدة gapi.auth2. يمكنك مواصلة استخدام وحدة gapi.client بأمان من Google API. مكتبة البرامج لـ JavaScript والاستفادة من إنشائها تلقائيًا طرق JavaScript القابلة للاستدعاء من مستند استكشاف، وإرسال طلبات بيانات متعددة من واجهة برمجة التطبيقات، وإدارة سياسة مشاركة الموارد المتعددة المصادر (CORS).

بسكويت

لا يتطلب إذن المستخدم استخدام ملفات تعريف الارتباط.

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

بيانات الاعتماد

تفصل "خدمات هوية Google" مصادقة المستخدم وتفويضه في عمليتان مختلفتان، وبيانات اعتماد المستخدم منفصلة: الرمز المميز للمعرف المستخدم أن يتم إرجاع المستخدم بشكل منفصل عن رمز الدخول المستخدم في التفويض.

لعرض هذه التغييرات، يُرجى الاطّلاع على أمثلة لبيانات الاعتماد.

التدفق الضمني

فصل مصادقة المستخدم وتفويضه عن طريق إزالة ملف المستخدم الشخصي ومعالجتها من تدفقات التفويض.

إزالة مراجع العميل المستندة إلى JavaScript لتسجيل الدخول إلى Google:

الطُرق

  • GoogleUser.getBasicProfile()
  • GoogleUser.getId()

مسار رمز التفويض

تفصل خدمات الهوية بيانات الاعتماد داخل المتصفح إلى رمز مميز للمعرف وإمكانية الوصول الرمز المميز. لا ينطبق هذا التغيير على بيانات الاعتماد التي يتم الحصول عليها من خلال الربط المباشر الطلبات إلى نقاط نهاية Google OAuth 2.0 من النظام الأساسي للخلفية أو من خلال المكتبات التي تعمل على خادم آمن على نظامك الأساسي مثل موقع Google عميل Node.js في واجهات برمجة التطبيقات

حالة الجلسة

في السابق، ساعدك تسجيل الدخول بحساب Google على إدارة حالة تسجيل دخول المستخدم من خلال:

أنت مسؤول عن إدارة حالة تسجيل الدخول وجلسات المستخدمين على موقعك الإلكتروني. التطبيق.

إزالة مراجع العميل المستندة إلى JavaScript لتسجيل الدخول إلى Google:

الكائنات:

  • gapi.auth2.SignInOptions

الطُرق:

  • GoogleAuth.attachClickHandler()
  • GoogleAuth.isSignedIn()
  • GoogleAuth.isSignedIn.get()
  • GoogleAuth.isSignedIn.listen()
  • GoogleAuth.signIn()
  • GoogleAuth.signOut()
  • GoogleAuth.currentUser.get()
  • GoogleAuth.currentUser.listen()
  • GoogleUser.isSignedIn()

إعداد بيانات العميل

حدِّث تطبيق الويب لإعداد برنامج رمز مميّز للقيمة الضمنية أو مسار رمز التفويض.

إزالة مراجع العميل المستندة إلى JavaScript لتسجيل الدخول إلى Google:

الكائنات:

  • gapi.auth2.ClientConfig
  • gapi.auth2.OfflineAccessOptions

الطُرق:

  • gapi.auth2.getAuthInstance()
  • GoogleUser.grant()

التدفق الضمني

إضافة كائن TokenClientConfig وinitTokenClient() استدعاء إلى تهيئة تطبيق الويب، متبعًا المثال في إعداد رمز مميز .

استبدال مراجع عميل JavaScript لتسجيل الدخول بحساب Google بـ Google خدمات الهوية:

الكائنات:

  • gapi.auth2.AuthorizeConfig مع TokenClientConfig

الطُرق:

  • gapi.auth2.init() مع google.accounts.oauth2.initTokenClient()

المَعلمات:

  • gapi.auth2.AuthorizeConfig.login_hint باستخدام TokenClientConfig.login_hint
  • "gapi.auth2.GoogleUser.getHostedDomain()" مع "TokenClientConfig.hd"

مسار رمز التفويض

إضافة كائن CodeClientConfig واستدعاء initCodeClient() لإعداده لتطبيق الويب، باتباع المثال في إعداد برنامج رمز برمجي.

عند التبديل من العملية الضمنية إلى مسار رمز التفويض:

إزالة مراجع عميل JavaScript لتسجيل الدخول إلى Google

الكائنات:

  • gapi.auth2.AuthorizeConfig

الطُرق:

  • gapi.auth2.init()

المَعلمات:

  • gapi.auth2.AuthorizeConfig.login_hint
  • gapi.auth2.GoogleUser.getHostedDomain()

طلب الرمز المميّز

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

التدفق الضمني

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

استبدال مراجع عميل JavaScript لتسجيل الدخول بحساب Google: بـ Google خدمات الهوية:

الطُرق:

  • gapi.auth2.authorize() مع TokenClient.requestAccessToken()
  • GoogleUser.reloadAuthResponse() باستخدام TokenClient.requestAccessToken()

إضافة رابط أو زر للاتصال بـ requestAccessToken() لبدء تدفق تجربة المستخدم المنبثق لطلب رمز الدخول، أو للحصول على رمز جديد عند انتهاء صلاحية الرمز المميّز الحالي.

تحديث قاعدة الرموز إلى:

  • ابدأ تدفق رمز OAuth 2.0 المميز باستخدام requestAccessToken().
  • يمكنك دعم التفويض المتزايد باستخدام requestAccessToken OverridableTokenClientConfig لفصل طلب واحد لعدة نطاقات إلى عدة طلبات أصغر.
  • اطلب رمزًا مميزًا جديدًا عند انتهاء صلاحية الرمز المميز الحالي أو عند إبطاله.

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

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

مسار رمز التفويض

إضافة رابط أو زر للاتصال بـ requestCode() من أجل طلب إذن الرمز البرمجي من Google. للحصول على مثال، يُرجى الاطّلاع على تدفق رموز OAuth 2.0.

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

معالجة الرموز المميّزة

إضافة معالجة الخطأ لرصد طلبات البيانات من واجهة Google API التي تعذّر تنفيذها عند انتهاء صلاحية أو يتم استخدام رمز دخول تم إبطاله، ولطلب رمز دخول جديد وصالح.

رمز حالة HTTP لرسالة الخطأ 401 Unauthorized وinvalid_token هو التي تعرضها Google APIs عند استخدام رمز دخول منتهي الصلاحية أو تم إبطاله. بالنسبة إلى يمكنك الاطّلاع على استجابة الرمز المميّز غير الصالح.

الرموز المميّزة المنتهية الصلاحية

رموز الدخول قصيرة الأجل، وغالبًا ما تكون صالحة لبضع دقائق فقط.

إبطال الرمز المميّز

يجوز لصاحب حساب Google إبطال الموافقة التي تم منحها سابقًا في أي وقت. التنفيذ ولذلك يلغي صلاحية رموز الدخول الحالية ورموز إعادة التحميل. قد يكون الإبطال تم إطلاقها من النظام الأساسي باستخدام revoke() أو من خلال Google .

استبدال مراجع عميل JavaScript لتسجيل الدخول بحساب Google: بـ Google خدمات الهوية:

الطُرق:

  • getAuthInstance().disconnect() مع google.accounts.oauth2.revoke()
  • GoogleUser.disconnect() مع google.accounts.oauth2.revoke()

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

تعرض Google مربّع إفادة الموافقة للمستخدم عند استخدام تطبيق الويب أو الخلفية النظام الأساسي رمز دخول. الاطّلاع على أمثلة على مربّعات حوار الموافقة المعروضة Google للمستخدمين.

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

تسجيل دخول المستخدم

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

  • تقليل عدد المرات التي يجب على المستخدم فيها تسجيل الدخول وطلب إذن الوصول إلى بدء عملية تسجيل الدخول إلى حساب Google إذا حدثت جلسة نشطة غير موجودة بالفعل.
  • استخدِم حقل بيانات الاعتماد email للرمز المميّز لرقم تعريف JWT مباشرةً كقيمة المَعلمة login_hint في CodeClientConfig أو TokenClientConfig الأخرى. ويكون هذا الأمر مفيدًا بشكل خاص إذا كانت منصتك لا تحافظ على نظام إدارة حساب المستخدم.
  • ابحث عن حساب Google واربطه بحساب مستخدم محلي حالي على منصّتك، ما يساعد على الحدّ من تكرار الحسابات على منصتك.
  • عند إنشاء حساب محلي جديد، يمكن تحديد مربّعات حوار عملية الاشتراك ومسارها منفصلة بوضوح عن مربعات حوار مصادقة المستخدم والتدفقات، مما يقلل عدد الخطوات المطلوبة وتحسين معدل الانسحاب.

بعد تسجيل الدخول وإصدار رمز الدخول، على المستخدمين تقديم الموافقة لتطبيقك للنطاقات المطلوبة.

بعد الموافقة، يتم عرض رمز دخول إلى جانب قائمة بالنطاقات التي تمت الموافقة عليها أو رفضها.

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

التدفق الضمني

استبدال مراجع عميل JavaScript لتسجيل الدخول بحساب Google بـ Google خدمات الهوية:

الكائنات:

  • gapi.auth2.AuthorizeResponse مع TokenClient.TokenResponse
  • gapi.auth2.AuthResponse مع TokenClient.TokenResponse

الطُرق:

  • GoogleUser.hasGrantedScopes() باستخدام google.accounts.oauth2.hasGrantedAllScopes()
  • GoogleUser.getGrantedScopes() باستخدام google.accounts.oauth2.hasGrantedAllScopes()

إزالة مراجع عميل JavaScript لتسجيل الدخول إلى Google:

الطُرق:

  • GoogleUser.getAuthResponse()

تحديث تطبيق الويب باستخدام hasGrantedAllScopes() hasGrantedAnyScope() باتّباع هذا المثال عن الأذونات الدقيقة.

مسار رمز التفويض

تحديث أو إضافة نقطة نهاية رمز التفويض إلى الخلفية من خلال اتّباع التعليمات الواردة في التعامل مع رمز المصادقة.

حدِّث نظامك الأساسي لاتّباع الخطوات الموضّحة في مقالة استخدام الرمز. دليل النموذج للتحقّق من صحة الطلب والحصول على رمز الدخول وإعادة التحميل الرمز المميز.

تحديث منصتك لتفعيل الميزات أو إيقافها بشكل انتقائي الوظائف استنادًا إلى النطاقات الفردية التي وافق عليها المستخدم باتباع إرشادات التفويض المتزايد وفحص نطاقات الوصول التي منحها المستخدم.

أمثلة التدفق الضمني

الطريقة القديمة

مكتبة عملاء GAPI

مثال على مكتبة برامج Google API للغة JavaScript قيد التشغيل في المتصفّح باستخدام مربّع حوار منبثق لطلب موافقة المستخدم

يتم تحميل الوحدة gapi.auth2 واستخدامها تلقائيًا بواسطة gapi.client.init()، وهكذا مخفية.

<!DOCTYPE html>
  <html>
    <head>
      <script src="https://apis.google.com/js/api.js"></script>
      <script>
        function start() {
          gapi.client.init({
            'apiKey': 'YOUR_API_KEY',
            'clientId': 'YOUR_CLIENT_ID',
            'scope': 'https://www.googleapis.com/auth/cloud-translation',
            'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
          }).then(function() {
            // Execute an API request which is returned as a Promise.
            // The method name language.translations.list comes from the API discovery.
            return gapi.client.language.translations.list({
              q: 'hello world',
              source: 'en',
              target: 'de',
            });
          }).then(function(response) {
            console.log(response.result.data.translations[0].translatedText);
          }, function(reason) {
            console.log('Error: ' + reason.result.error.message);
          });
        };

        // Load the JavaScript client library and invoke start afterwards.
        gapi.load('client', start);
      </script>
    </head>
    <body>
      <div id="results"></div>
    </body>
  </html>

مكتبة برامج JavaScript

OAuth 2.0 لتطبيقات الويب من جانب العميل الذي يتم تشغيله في المتصفح باستخدام مربّع حوار منبثق لطلب موافقة المستخدم

يتم تحميل وحدة gapi.auth2 يدويًا.

<!DOCTYPE html>
<html><head></head><body>
<script>
  var GoogleAuth;
  var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  function handleClientLoad() {
    // Load the API's client and auth2 modules.
    // Call the initClient function after the modules load.
    gapi.load('client:auth2', initClient);
  }

  function initClient() {
    // In practice, your app can retrieve one or more discovery documents.
    var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

    // Initialize the gapi.client object, which app uses to make API requests.
    // Get API key and client ID from API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

      // Call handleAuthClick function when user clicks on
      //      "Sign In/Authorize" button.
      $('#sign-in-or-out-button').click(function() {
        handleAuthClick();
      });
      $('#revoke-access-button').click(function() {
        revokeAccess();
      });
    });
  }

  function handleAuthClick() {
    if (GoogleAuth.isSignedIn.get()) {
      // User is authorized and has clicked "Sign out" button.
      GoogleAuth.signOut();
    } else {
      // User is not signed in. Start Google auth flow.
      GoogleAuth.signIn();
    }
  }

  function revokeAccess() {
    GoogleAuth.disconnect();
  }

  function setSigninStatus() {
    var user = GoogleAuth.currentUser.get();
    var isAuthorized = user.hasGrantedScopes(SCOPE);
    if (isAuthorized) {
      $('#sign-in-or-out-button').html('Sign out');
      $('#revoke-access-button').css('display', 'inline-block');
      $('#auth-status').html('You are currently signed in and have granted ' +
          'access to this app.');
    } else {
      $('#sign-in-or-out-button').html('Sign In/Authorize');
      $('#revoke-access-button').css('display', 'none');
      $('#auth-status').html('You have not authorized this app or you are ' +
          'signed out.');
    }
  }

  function updateSigninStatus() {
    setSigninStatus();
  }
</script>

<button id="sign-in-or-out-button"
        style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
        style="display: none; margin-left: 25px">Revoke access</button>

<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body></html>

نقاط نهاية OAuth 2.0

OAuth 2.0 لتطبيقات الويب من جانب العميل الذي يعمل في المتصفح باستخدام تعيد التوجيه إلى Google للحصول على موافقة المستخدم.

يعرض هذا المثال المكالمات المباشرة إلى نقاط نهاية OAuth 2.0 في Google من متصفّح المستخدم ولا يستخدم الوحدة gapi.auth2 أو JavaScript المكتبة.

<!DOCTYPE html>
<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*

    *   Create form to request access token from Google's OAuth 2.0 server.
 */
function oauth2SignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

الطريقة الجديدة

أنظمة المعلومات الجغرافية فقط

لا يعرض هذا المثال سوى مكتبة JavaScript لخدمة Google Identity. استخدام نموذج الرمز المميّز ومربّع الحوار المنبثق للحصول على موافقة المستخدم. من المهم لتوضيح أقل عدد من الخطوات المطلوبة لتهيئة العميل وطلب رمز الدخول والحصول عليه بالإضافة إلى طلب واجهة برمجة تطبيقات Google.

<!DOCTYPE html>
<html>
  <head>
    <script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
  </head>
  <body>
    <script>
      var client;
      var access_token;

      function initClient() {
        client = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_CLIENT_ID',
          scope: 'https://www.googleapis.com/auth/calendar.readonly \
                  https://www.googleapis.com/auth/contacts.readonly',
          callback: (tokenResponse) => {
            access_token = tokenResponse.access_token;
          },
        });
      }
      function getToken() {
        client.requestAccessToken();
      }
      function revokeToken() {
        google.accounts.oauth2.revoke(access_token, () => {console.log('access token revoked')});
      }
      function loadCalendar() {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
        xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
        xhr.send();
      }
    </script>
    <h1>Google Identity Services Authorization Token model</h1>
    <button onclick="getToken();">Get access token</button><br><br>
    <button onclick="loadCalendar();">Load Calendar</button><br><br>
    <button onclick="revokeToken();">Revoke token</button>
  </body>
</html>

واجهة برمجة تطبيقات GAPI غير متزامنة/في انتظار المعالجة

يوضح هذا المثال كيفية إضافة مكتبة Google Identity Service باستخدام نموذج الرمز المميّز، وإزالة وحدة gapi.auth2، وطلب واجهة برمجة تطبيقات باستخدام مكتبة برامج Google API للغة JavaScript

تُستخدم الوعود غير المتزامنة والانتظارية لفرض ترتيب تحميل المكتبة اكتشاف أخطاء التفويض وإعادة المحاولة. لا يتم إجراء طلب بيانات من واجهة برمجة التطبيقات إلا بعد إدخال يتوفر رمز الدخول.

من المتوقع أن يضغط المستخدمون على الزر "إظهار التقويم" زر عند إدخال رمز الدخول مفقود عند تحميل الصفحة لأول مرة، أو في وقت لاحق بعد رمز الدخول منتهي الصلاحية.

<!DOCTYPE html>
<html>
<head></head>
<body>
  <h1>GAPI with GIS async/await</h1>
  <button id="showEventsBtn" onclick="showEvents();">Show Calendar</button><br><br>
  <button id="revokeBtn" onclick="revokeToken();">Revoke access token</button>

  <script>

    const gapiLoadPromise = new Promise((resolve, reject) => {
      gapiLoadOkay = resolve;
      gapiLoadFail = reject;
    });
    const gisLoadPromise = new Promise((resolve, reject) => {
      gisLoadOkay = resolve;
      gisLoadFail = reject;
    });

    var tokenClient;

    (async () => {
      document.getElementById("showEventsBtn").style.visibility="hidden";
      document.getElementById("revokeBtn").style.visibility="hidden";

      // First, load and initialize the gapi.client
      await gapiLoadPromise;
      await new Promise((resolve, reject) => {
        // NOTE: the 'auth2' module is no longer loaded.
        gapi.load('client', {callback: resolve, onerror: reject});
      });
      await gapi.client.init({
        // NOTE: OAuth2 'scope' and 'client_id' parameters have moved to initTokenClient().
      })
      .then(function() {  // Load the Calendar API discovery document.
        gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
      });

      // Now load the GIS client
      await gisLoadPromise;
      await new Promise((resolve, reject) => {
        try {
          tokenClient = google.accounts.oauth2.initTokenClient({
              client_id: 'YOUR_CLIENT_ID',
              scope: 'https://www.googleapis.com/auth/calendar.readonly',
              prompt: 'consent',
              callback: '',  // defined at request time in await/promise scope.
          });
          resolve();
        } catch (err) {
          reject(err);
        }
      });

      document.getElementById("showEventsBtn").style.visibility="visible";
      document.getElementById("revokeBtn").style.visibility="visible";
    })();

    async function getToken(err) {

      if (err.result.error.code == 401 || (err.result.error.code == 403) &&
          (err.result.error.status == "PERMISSION_DENIED")) {

        // The access token is missing, invalid, or expired, prompt for user consent to obtain one.
        await new Promise((resolve, reject) => {
          try {
            // Settle this promise in the response callback for requestAccessToken()
            tokenClient.callback = (resp) => {
              if (resp.error !== undefined) {
                reject(resp);
              }
              // GIS has automatically updated gapi.client with the newly issued access token.
              console.log('gapi.client access token: ' + JSON.stringify(gapi.client.getToken()));
              resolve(resp);
            };
            tokenClient.requestAccessToken();
          } catch (err) {
            console.log(err)
          }
        });
      } else {
        // Errors unrelated to authorization: server errors, exceeding quota, bad requests, and so on.
        throw new Error(err);
      }
    }

    function showEvents() {

      // Try to fetch a list of Calendar events. If a valid access token is needed,
      // prompt to obtain one and then retry the original request.
      gapi.client.calendar.events.list({ 'calendarId': 'primary' })
      .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
      .catch(err  => getToken(err))  // for authorization errors obtain an access token
      .then(retry => gapi.client.calendar.events.list({ 'calendarId': 'primary' }))
      .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
      .catch(err  => console.log(err)); // cancelled by user, timeout, etc.
    }

    function revokeToken() {
      let cred = gapi.client.getToken();
      if (cred !== null) {
        google.accounts.oauth2.revoke(cred.access_token, () => {console.log('Revoked: ' + cred.access_token)});
        gapi.client.setToken('');
      }
    }

  </script>

  <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoadOkay()" onerror="gapiLoadFail(event)"></script>
  <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoadOkay()" onerror="gisLoadFail(event)"></script>

</body>
</html>

معاودة الاتصال من GAPI

يوضح هذا المثال كيفية إضافة مكتبة Google Identity Service باستخدام نموذج الرمز المميّز، وإزالة وحدة gapi.auth2، وطلب واجهة برمجة تطبيقات باستخدام مكتبة برامج Google API للغة JavaScript

يتم استخدام المتغيّرات لفرض ترتيب تحميل المكتبة. يتم إجراء طلبات البيانات من GAPI من داخل رد الاتصال بعد عرض رمز دخول صالح.

من المتوقع أن يضغط المستخدمون على زر "إظهار التقويم" عندما تكون الصفحة هي الأولى المستخدم ومرة أخرى عندما يريد تحديث معلومات "تقويم Google".

<!DOCTYPE html>
<html>
<head>
  <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoad()"></script>
  <script async defer src="https://accounts.google.com/gsi/client" onload="gisInit()"></script>
</head>
<body>
  <h1>GAPI with GIS callbacks</h1>
  <button id="showEventsBtn" onclick="showEvents();">Show Calendar</button><br><br>
  <button id="revokeBtn" onclick="revokeToken();">Revoke access token</button>
  <script>
    let tokenClient;
    let gapiInited;
    let gisInited;

    document.getElementById("showEventsBtn").style.visibility="hidden";
    document.getElementById("revokeBtn").style.visibility="hidden";

    function checkBeforeStart() {
       if (gapiInited && gisInited){
          // Start only when both gapi and gis are initialized.
          document.getElementById("showEventsBtn").style.visibility="visible";
          document.getElementById("revokeBtn").style.visibility="visible";
       }
    }

    function gapiInit() {
      gapi.client.init({
        // NOTE: OAuth2 'scope' and 'client_id' parameters have moved to initTokenClient().
      })
      .then(function() {  // Load the Calendar API discovery document.
        gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
        gapiInited = true;
        checkBeforeStart();
      });
    }

    function gapiLoad() {
        gapi.load('client', gapiInit)
    }

    function gisInit() {
     tokenClient = google.accounts.oauth2.initTokenClient({
                client_id: 'YOUR_CLIENT_ID',
                scope: 'https://www.googleapis.com/auth/calendar.readonly',
                callback: '',  // defined at request time
            });
      gisInited = true;
      checkBeforeStart();
    }

    function showEvents() {

      tokenClient.callback = (resp) => {
        if (resp.error !== undefined) {
          throw(resp);
        }
        // GIS has automatically updated gapi.client with the newly issued access token.
        console.log('gapi.client access token: ' + JSON.stringify(gapi.client.getToken()));

        gapi.client.calendar.events.list({ 'calendarId': 'primary' })
        .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
        .catch(err => console.log(err));

        document.getElementById("showEventsBtn").innerText = "Refresh Calendar";
      }

      // Conditionally ask users to select the Google Account they'd like to use,
      // and explicitly obtain their consent to fetch their Calendar.
      // NOTE: To request an access token a user gesture is necessary.
      if (gapi.client.getToken() === null) {
        // Prompt the user to select a Google Account and asked for consent to share their data
        // when establishing a new session.
        tokenClient.requestAccessToken({prompt: 'consent'});
      } else {
        // Skip display of account chooser and consent dialog for an existing session.
        tokenClient.requestAccessToken({prompt: ''});
      }
    }

    function revokeToken() {
      let cred = gapi.client.getToken();
      if (cred !== null) {
        google.accounts.oauth2.revoke(cred.access_token, () => {console.log('Revoked: ' + cred.access_token)});
        gapi.client.setToken('');
        document.getElementById("showEventsBtn").innerText = "Show Calendar";
      }
    }
  </script>
</body>
</html>

أمثلة على مسار رمز التفويض

يمكن لتجربة المستخدم في النافذة المنبثقة لمكتبة "خدمة Google Identity" استخدام إعادة توجيه عنوان URL إرجاع رمز تفويض مباشرةً إلى نقطة نهاية الرمز المميز للخلفية أو تشغيل معالج استدعاء JavaScript في متصفح المستخدم الذي يقوم بإنشاء خادم وكيل بشكل أفضل على منصتك. في كلتا الحالتين، ستكتمل المنصة الخلفية مسار OAuth 2.0 للحصول على رمز دخول وإعادة تحميل صالحَين.

الطريقة القديمة

تطبيقات الويب من جهة الخادم

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

<!DOCTYPE html>
<html>
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    <script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
    <script>
      function start() {
        gapi.load('auth2', function() {
          auth2 = gapi.auth2.init({
            client_id: 'YOUR_CLIENT_ID',
            api_key: 'YOUR_API_KEY',
            discovery_docs: ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
            // Scopes to request in addition to 'profile' and 'email'
            scope: 'https://www.googleapis.com/auth/cloud-translation',
          });
        });
      }
      function signInCallback(authResult) {
        if (authResult['code']) {
          console.log("sending AJAX request");
          // Send authorization code obtained from Google to backend platform
          $.ajax({
            type: 'POST',
            url: 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URL',
            // Always include an X-Requested-With header to protect against CSRF attacks.
            headers: {
              'X-Requested-With': 'XMLHttpRequest'
            },
            contentType: 'application/octet-stream; charset=utf-8',
            success: function(result) {
              console.log(result);
            },
            processData: false,
            data: authResult['code']
          });
        } else {
          console.log('error: failed to obtain authorization code')
        }
      }
    </script>
  </head>
  <body>
    <button id="signinButton">Sign In With Google</button>
    <script>
      $('#signinButton').click(function() {
        // Obtain an authorization code from Google
        auth2.grantOfflineAccess().then(signInCallback);
      });
    </script>
  </body>
</html>

HTTP/REST باستخدام إعادة التوجيه

استخدام OAuth 2.0 مع تطبيقات خادم الويب لإرسال رمز التفويض من متصفح المستخدم إلى النظام الأساسي للخلفية. يتم التعامل مع موافقة المستخدم من خلال إعادة توجيه متصفح المستخدم إلى Google.

/\*
 \* Create form to request access token from Google's OAuth 2.0 server.
 \*/
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';
  // Create &lt;form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);
  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client\_id': 'YOUR_CLIENT_ID',
                'redirect\_uri': 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URL',
                'response\_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include\_granted\_scopes': 'true',
                'state': 'pass-through value'};
  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

الطريقة الجديدة

تجربة المستخدم في نافذة GIS المنبثقة

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

<!DOCTYPE html>
<html>
  <head>
    <script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
  </head>
  <body>
    <script>
      var client;
      function initClient() {
        client = google.accounts.oauth2.initCodeClient({
          client_id: 'YOUR_CLIENT_ID',
          scope: 'https://www.googleapis.com/auth/calendar.readonly',
          ux_mode: 'popup',
          callback: (response) => {
            var code_receiver_uri = 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URI',
            // Send auth code to your backend platform
            const xhr = new XMLHttpRequest();
            xhr.open('POST', code_receiver_uri, true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            xhr.onload = function() {
              console.log('Signed in as: ' + xhr.responseText);
            };
            xhr.send('code=' + response.code);
            // After receipt, the code is exchanged for an access token and
            // refresh token, and the platform then updates this web app
            // running in user's browser with the requested calendar info.
          },
        });
      }
      function getAuthCode() {
        // Request authorization code and obtain user consent
        client.requestCode();
      }
    </script>
    <button onclick="getAuthCode();">Load Your Calendar</button>
  </body>
</html>

تجربة المستخدم في إعادة توجيه GIS

يتوافق نموذج رمز التفويض مع النافذة المنبثقة ويعيد توجيه أوضاع تجربة المستخدم إلى إرسال رمز تفويض لكل مستخدم إلى نقطة النهاية التي تستضيفها منصّتك. يظهر وضع "تجربة المستخدم" لإعادة التوجيه هنا:

<!DOCTYPE html>
<html>
  <head>
    <script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
  </head>
  <body>
    <script>
      var client;
      function initClient() {
        client = google.accounts.oauth2.initCodeClient({
          client_id: 'YOUR_CLIENT_ID',
          scope: 'https://www.googleapis.com/auth/calendar.readonly \
                  https://www.googleapis.com/auth/photoslibrary.readonly',
          ux_mode: 'redirect',
          redirect_uri: 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URI'
        });
      }
      // Request an access token
      function getAuthCode() {
        // Request authorization code and obtain user consent
        client.requestCode();
      }
    </script>
    <button onclick="getAuthCode();">Load Your Calendar</button>
  </body>
</html>

مكتبات JavaScript

خدمات هوية Google هي مكتبة JavaScript واحدة تُستخدَم للمستخدمين ومصادقة وتفويض يدمج ويستبدل الميزات الوظائف المتوفرة في مكتبات ووحدات مختلفة:

الإجراءات التي يجب اتخاذها عند نقل البيانات إلى "خدمات الهوية":

مكتبة JavaScript الحالية مكتبة JavaScript جديدة ملاحظات
apis.google.com/js/api.js accounts.google.com/gsi/client أضف مكتبة جديدة واتبع التدفق الضمني.
apis.google.com/js/client.js accounts.google.com/gsi/client إضافة مكتبة جديدة ومسار رمز التفويض

مرجع سريع للمكتبة

مقارنة العنصر والطريقة بين تطبيق JavaScript لتسجيل الدخول باستخدام القديم العميل ومكتبة خدمات Google Identity الجديدة ملاحظات تشمل معلومات إضافية وإجراءات يجب اتخاذها أثناء نقل البيانات.

الإصدار القديم جديد ملاحظات
الكائن GoogleAuth والطرق المرتبطة به:
GoogleAuth.attachClickHandler() إزالة
GoogleAuth.currentUser.get() إزالة
GoogleAuth.currentUser.listen() إزالة
GoogleAuth.disconnect() google.accounts.oauth2.revoke استبدِل القديم بجديد. قد يتم إبطال الأذونات أيضًا من خلال الرابط https://myaccount.google.com/permissions
GoogleAuth.grantOfflineAccess() عليك إزالته واتّباع مسار رمز التفويض.
GoogleAuth.isSignedIn.get() إزالة
GoogleAuth.isSignedIn.listen() إزالة
GoogleAuth.signIn() إزالة
GoogleAuth.signOut() إزالة
GoogleAuth.then() إزالة
GoogleUser والطرق المرتبطة به:
GoogleUser.disconnect() google.accounts.id.revoke استبدِل القديم بجديد. قد يتم إبطال الأذونات أيضًا من خلال الرابط https://myaccount.google.com/permissions
GoogleUser.getAuthResponse() requestCode() or requestAccessToken() استبدال القديم بجديد
GoogleUser.getBasicProfile() إزالة. يمكنك استخدام الرمز المميّز لرقم التعريف بدلاً من ذلك، ويمكنك الاطّلاع على المقالة نقل البيانات من صفحة "تسجيل الدخول بحساب Google".
GoogleUser.getGrantedScopes() hasGrantedAnyScope() استبدال القديم بجديد
GoogleUser.getHostedDomain() إزالة
GoogleUser.getId() إزالة
GoogleUser.grantOfflineAccess() عليك إزالته واتّباع مسار رمز التفويض.
GoogleUser.grant() إزالة
GoogleUser.hasGrantedScopes() hasGrantedAnyScope() استبدال القديم بجديد
GoogleUser.isSignedIn() إزالة
GoogleUser.reloadAuthResponse() requestAccessToken() أزِل المكالمة القديمة أو المكالمة الجديدة لاستبدال رمز الدخول منتهي الصلاحية أو الذي تم إبطاله.
gapi.auth2 والطرق المرتبطة به:
عنصر gapi.auth2.AuthorizeConfig TokenClientConfig أو CodeClientConfig استبدال القديم بجديد
عنصر gapi.auth2.AuthorizeResponse إزالة
عنصر gapi.auth2.AuthResponse إزالة
gapi.auth2.authorize() requestCode() or requestAccessToken() استبدال القديم بجديد
gapi.auth2.ClientConfig() TokenClientConfig أو CodeClientConfig استبدال القديم بجديد
gapi.auth2.getAuthInstance() إزالة
gapi.auth2.init() initTokenClient() or initCodeClient() استبدال القديم بجديد
الكائن gapi.auth2.offlineAccessOptions إزالة
عنصر gapi.auth2.SignInOptions إزالة
الكائن gapi.signin2 والطرق المرتبطة به:
gapi.signin2.render() إزالة. جارٍ تحميل HTML DOM g_id_signin العنصر أو استدعاء JavaScript google.accounts.id.renderButton تؤدي إلى تسجيل دخول المستخدم إلى حساب Google.

أمثلة لبيانات الاعتماد

بيانات الاعتماد الحالية

مكتبة منصة "تسجيل الدخول بحساب Google" ومكتبة برامج Google API للنطاق إعادة تفعيل JavaScript أو المكالمات المباشرة إلى نقاط نهاية Google Auth 2.0 كل من رمز الدخول OAuth 2.0 والرمز المميز لمعرف اتصال OpenID في الاستجابة.

مثال على إجابة تحتوي على access_token وid_token:

  {
    "token_type": "Bearer",
    "access_token": "ya29.A0ARrdaM-SmArZaCIh68qXsZSzyeU-8mxhQERHrP2EXtxpUuZ-3oW8IW7a6D2J6lRnZrRj8S6-ZcIl5XVEqnqxq5fuMeDDH_6MZgQ5dgP7moY-yTiKR5kdPm-LkuPM-mOtUsylWPd1wpRmvw_AGOZ1UUCa6UD5Hg",
    "scope": "https://www.googleapis.com/auth/calendar.readonly",
    "login_hint": "AJDLj6I2d1RH77cgpe__DdEree1zxHjZJr4Q7yOisoumTZUmo5W2ZmVFHyAomUYzLkrluG-hqt4RnNxrPhArd5y6p8kzO0t8xIfMAe6yhztt6v2E-_Bb4Ec3GLFKikHSXNh5bI-gPrsI",
    "expires_in": 3599,
    "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjkzNDFhYmM0MDkyYjZmYzAzOGU0MDNjOTEwMjJkZDNlNDQ1MzliNTYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE3NzI2NDMxNjUxOTQzNjk4NjAwIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6IkJBSW55TjN2MS1ZejNLQnJUMVo0ckEiLCJuYW1lIjoiQnJpYW4gRGF1Z2hlcnR5IiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hLS9BT2gxNEdnenAyTXNGRGZvbVdMX3VDemRYUWNzeVM3ZGtxTE5ybk90S0QzVXNRPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IkJyaWFuIiwiZmFtaWx5X25hbWUiOiJEYXVnaGVydHkiLCJsb2NhbGUiOiJlbiIsImlhdCI6MTYzODk5MTYzOCwiZXhwIjoxNjM4OTk1MjM4LCJqdGkiOiI5YmRkZjE1YWFiNzE2ZDhjYmJmNDYwMmM1YWM3YzViN2VhMDQ5OTA5In0.K3EA-3Adw5HA7O8nJVCsX1HmGWxWzYk3P7ViVBb4H4BoT2-HIgxKlx1mi6jSxIUJGEekjw9MC-nL1B9Asgv1vXTMgoGaNna0UoEHYitySI23E5jaMkExkTSLtxI-ih2tJrA2ggfA9Ekj-JFiMc6MuJnwcfBTlsYWRcZOYVw3QpdTZ_VYfhUu-yERAElZCjaAyEXLtVQegRe-ymScra3r9S92TA33ylMb3WDTlfmDpWL0CDdDzby2asXYpl6GQ7SdSj64s49Yw6mdGELZn5WoJqG7Zr2KwIGXJuSxEo-wGbzxNK-mKAiABcFpYP4KHPEUgYyz3n9Vqn2Tfrgp-g65BQ",
    "session_state": {
      "extraQueryParams": {
        "authuser": "0"
      }
    },
    "first_issued_at": 1638991637982,
    "expires_at": 1638995236982,
    "idpId": "google"
  }

بيانات اعتماد "خدمات هوية Google"

تعرض مكتبة خدمات هوية Google ما يلي:

  • رمز دخول عند استخدامه للتفويض:

    {
      "access_token": "ya29.A0ARrdaM_LWSO-uckLj7IJVNSfnUityT0Xj-UCCrGxFQdxmLiWuAosnAKMVQ2Z0LLqeZdeJii3TgULp6hR_PJxnInBOl8UoUwWoqsrGQ7-swxgy97E8_hnzfhrOWyQBmH6zs0_sUCzwzhEr_FAVqf92sZZHphr0g",
      "token_type": "Bearer",
      "expires_in": 3599,
      "scope": "https://www.googleapis.com/auth/calendar.readonly"
    }
    
  • أو رمز مميز للمعرّف عند استخدامه للمصادقة:

    {
      "clientId": "538344653255-758c5h5isc45vgk27d8h8deabovpg6to.apps.googleusercontent.com",
      "credential": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxODkyZWI0OWQ3ZWY5YWRmOGIyZTE0YzA1Y2EwZDAzMjcxNGEyMzciLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2MzkxNTcyNjQsImF1ZCI6IjUzODM0NDY1MzI1NS03NThjNWg1aXNjNDV2Z2syN2Q4aDhkZWFib3ZwZzZ0by5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjExNzcyNjQzMTY1MTk0MzY5ODYwMCIsIm5vbmNlIjoiZm9vYmFyIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwibmFtZSI6IkJyaWFuIERhdWdoZXJ0eSIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQU9oMTRHZ3pwMk1zRkRmb21XTF91Q3pkWFFjc3lTN2RrcUxOcm5PdEtEM1VzUT1zOTYtYyIsImdpdmVuX25hbWUiOiJCcmlhbiIsImZhbWlseV9uYW1lIjoiRGF1Z2hlcnR5IiwiaWF0IjoxNjM5MTU3NTY0LCJleHAiOjE2MzkxNjExNjQsImp0aSI6IjRiOTVkYjAyZjU4NDczMmUxZGJkOTY2NWJiMWYzY2VhYzgyMmI0NjUifQ.Cr-AgMsLFeLurnqyGpw0hSomjOCU4S3cU669Hyi4VsbqnAV11zc_z73o6ahe9Nqc26kPVCNRGSqYrDZPfRyTnV6g1PIgc4Zvl-JBuy6O9HhClAK1HhMwh1FpgeYwXqrng1tifmuotuLQnZAiQJM73Gl-J_6s86Buo_1AIx5YAKCucYDUYYdXBIHLxrbALsA5W6pZCqqkMbqpTWteix-G5Q5T8LNsfqIu_uMBUGceqZWFJALhS9ieaDqoxhIqpx_89QAr1YlGu_UO6R6FYl0wDT-nzjyeF5tonSs3FHN0iNIiR3AMOHZu7KUwZaUdHg4eYkU-sQ01QNY_11keHROCRQ",
      "select_by": "user"
    }
    

استجابة الرمز المميّز غير صالحة

مثال على ردّ من Google عند محاولة تقديم طلب من واجهة برمجة التطبيقات باستخدام رمز دخول منتهي الصلاحية أو تم إبطاله أو غير صالح:

عناوين استجابة HTTP

  www-authenticate: Bearer realm="https://accounts.google.com/", error="invalid_token"

نص الاستجابة

  {
    "error": {
      "code": 401,
      "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
      "errors": [
        {
          "message": "Invalid Credentials",
          "domain": "global",
          "reason": "authError",
          "location": "Authorization",
          "locationType": "header"
        }
      ],
      "status": "UNAUTHENTICATED"
    }
  }