نقل البيانات إلى خدمات Google Identity

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

نظرة عامة

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

يقدم هذا الدليل تعليمات للترحيل من هذه المكتبات إلى مكتبة خدمات هوية Google.

من خلال اتباع هذا الدليل، سيمكنك:

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

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

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

تحديد تدفق التفويض

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

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

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

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

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

  • يستند التنفيذ إلى:

  • يتم تنفيذ تطبيقك في كل من متصفح المستخدم وعلى النظام الأساسي الخلفي.

  • تستضيف منصتك الخلفية نقطة نهاية رمز التفويض.

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

  • تتم إدارة الرموز المميزة للتحديث وتخزينها من خلال النظام الأساسي الخلفي.

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

اختيار تدفق التفويض

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

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

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

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

تدفق ضمني

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

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

تدفق رمز التفويض

يتم تسليم رمز تفويض لكل مستخدم صادر عن Google إلى النظام الأساسي للواجهة الخلفية، حيث يتم استبداله برمز دخول ورمز تحديث.

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

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

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

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

تحديد الشفرة المتأثرة والاختبار

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

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

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

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

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

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

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

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

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

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

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

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

الميزة Cookies

لا يتطلب تفويض المستخدم استخدام ملفات تعريف الارتباط.

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

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

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

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

تدفق ضمني

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

إزالة هذه مراجع برنامج JavaScript لتسجيل الدخول بحساب Google:

الطُرق

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

تدفق رمز التفويض

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

حالة الجلسة

في السابق، كانت ميزة "تسجيل الدخول بحساب 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.hint.
  • gapi.auth2.GoogleUser.getHostedDomain() مع TokenClientConfig.hosted_domain.

تدفق رمز التفويض

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

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

إزالة مراجع برنامج 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.

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

التعامل مع الرموز المميزة

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

يتم عرض رمز حالة 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 والمتصفّح عندما يفتح المستخدم تطبيقك لأول مرة، حيث يؤدي ذلك إلى تقديم المزايا التالية:

  • يؤدي هذا الإجراء إلى تقليل عدد مرات تسجيل دخول المستخدم إلى الحد الأدنى، ما يؤدي إلى طلب رمز دخول للدخول لبدء عملية تسجيل الدخول إلى حساب Google في حال عدم توفُّر جلسة نشطة.
  • استخدم الحقل "معرّف JWT" credential email كقيمة كقيمة للمعلمة 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>

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

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

يعرض هذا المثال مكتبة جافا سكريبت لخدمة 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>

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

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

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

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

<!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 باستخدام نموذج الرمز المميز، وإزالة وحدة gapi.auth2، واستدعاء واجهة برمجة التطبيقات باستخدام مكتبة برامج Google API لجافا سكريبت.

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

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

<!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" إما إعادة توجيه عنوان 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

يعرض هذا المثال مكتبة جافا سكريبت لخدمة 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

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

<!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 والمكتبة الجديدة خدمات الهوية من Google والملاحظات التي تتضمن معلومات إضافية وإجراءات يمكن اتخاذها أثناء نقل البيانات.

الإصدار القديم New (جديد) ملاحظات
كائن 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.the() إزالة
كائن GoogleUser والطرق المقترنة به:
GoogleUser.disconnect() google.accounts.id.revoke استبدال القديم بالجديد. وقد يحدث الإبطال أيضًا من https://myaccount.google.com/permissions
GoogleUser.getAuthResponse() requestCode() أو requestAccessToken() استبدال القديم بالجديد
GoogleUser.getBasicProfile() إزالة. استخدِم "الرمز المميز لرقم التعريف" بدلاً من ذلك، يُرجى الاطِّلاع على نقل البيانات من تسجيل الدخول بحساب Google.
GoogleUser.getGrantedScopes() hasGrantedanyScope() استبدال القديم بالجديد
GoogleUser.getHostDomain() إزالة
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.authorization() requestCode() أو requestAccessToken() استبدال القديم بالجديد
gapi.auth2.ClientConfig() TokenClientConfig أو CodeClientConfig استبدال القديم بالجديد
gapi.auth2.getAuthInstance() إزالة
gapi.auth2.init() initTokenClient() أو initCodeClient() استبدال القديم بالجديد
كائن gapi.auth2.OfflineAccessOptions إزالة
كائن gapi.auth2.SignInOptions إزالة
gapi.signin2 والطرق المقترنة به:
gapi.signin2.render() إزالة. يؤدي تحميل HTML DOM للعنصر g_id_signin أو استدعاء JS إلى google.accounts.id.renderButton إلى تسجيل دخول المستخدم إلى حساب Google.

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

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

تعرض مكتبة النظام الأساسي لتسجيل الدخول بحساب Google، أو مكتبة عميل واجهة برمجة تطبيقات Google لجافا سكريبت، أو المكالمات المباشرة إلى نقاط نهاية Google Auth 2.0 رمزًا للدخول إلى OAuth 2.0 ورمزًا مميزًا لـ OpenID Connect ID في استجابة واحدة.

مثال على رد يحتوي على كل من 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 Identity

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

  • أحد رموز الدخول عند استخدامه للتفويض:
  {
    "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"
    }
  }