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

نظرة عامة

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

يقدِّم هذا الدليل تعليمات لنقل البيانات من هذه المكتبات إلى مكتبة Google Identity Services.

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

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

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

إذا كنت تبحث عن المصادقة على اشتراك المستخدم وتسجيل الدخول، يُرجى الاطّلاع على نقل البيانات من خلال تسجيل الدخول بحساب Google بدلاً من ذلك.

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

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

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

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

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

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

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

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

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

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

  • تتم إدارة الرموز المميّزة لإعادة التحميل وتخزينها من خلال المنصة الخلفية.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

في التطبيقات الكبيرة أو المعقّدة، قد يصعب العثور على جميع الرموز المتأثرة بإيقاف وحدة 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 Services محل استخدام الوحدة gapi.auth2. يمكنك متابعة استخدام الوحدة gapi.client بأمان من مكتبة برامج واجهة Google API للغة JavaScript، والاستفادة من الإنشاء التلقائي لطُرق JavaScript القابلة للاستدعاء من مستند استكشاف، وتجميع طلبات البيانات من واجهة برمجة التطبيقات المتعددة، ووظيفة إدارة CORS.

بسكويت

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

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

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

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

للاطّلاع على هذه التغييرات، يمكنك الاطّلاع على مثال على بيانات الاعتماد.

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

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

أزِل المراجع التالية لبرنامج JavaScript "تسجيل الدخول بحساب Google":

الطُرق

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

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

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

حالة الجلسة

في السابق، ساعدك "تسجيل الدخول بحساب 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() لإعداد تطبيق الويب، باتّباع المثال الوارد في إعداد برنامج Code Client.

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

إزالة مراجع برنامج 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 Identity" عملية إعادة التحميل التلقائية للرمز المميز. يجب تحديث تطبيق الويب لاكتشاف رمز الدخول منتهي الصلاحية وطلب رمز جديد. لمزيد من المعلومات، يُرجى الاطّلاع على قسم "التعامل مع الرموز المميّزة" أدناه.

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

أضِف رابطًا أو زرًا للاتصال برقم requestCode() من أجل طلب رمز تفويض من Google. على سبيل المثال، اطّلِع على تشغيل تدفق رمز OAuth 2.0.

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

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

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

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

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

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

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

يجوز لمالك حساب 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 email كقيمة للمعلّمة 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 باستخدام نموذج الرمز المميز، وإزالة وحدة 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 باستخدام نموذج الرمز المميز، وإزالة وحدة 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 Identity Services هي مكتبة واحدة من 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 Identity الجديدة والملاحظات مع معلومات وإجراءات إضافية يجب اتخاذها أثناء نقل البيانات.

الإصدار القديم 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.then() إزالة
الكائن GoogleUser والطرق المرتبطة به:
GoogleUser.disconnect() google.accounts.id.revoke يمكنك استبدال القديم بجديد. قد يتم الإبطال أيضًا من خلال الرابط https://myaccount.google.com/permissions
GoogleUser.getAuthResponse() requestCode() أو requestAccessToken() استبدال القديمة بأخرى جديدة
GoogleUser.getBasicProfile() إزالة. استخدِم الرمز المميّز لرقم التعريف بدلاً من ذلك، يُرجى الاطّلاع على نقل البيانات من تسجيل الدخول بحساب Google.
GoogleUser.getGrantedScopes() hasgrantsedAnyScope() استبدال القديمة بأخرى جديدة
GoogleUser.gethostDomain() إزالة
GoogleUser.getId() إزالة
GoogleUser.grantofflineAccess() يُرجى الإزالة، ثم اتّباع مسار رمز التفويض.
GoogleUser.grant() إزالة
GoogleUser.hasGrantedScopes() hasgrantsedAnyScope() استبدال القديمة بأخرى جديدة
GoogleUser.isSignedIn() إزالة
GoogleUser.reloadAuthResponse() requestAccessToken() عليك إزالة القديم أو طلب جديد لاستبدال رمز الدخول المنتهي الصلاحية أو الذي تم إبطاله.
gapi.auth2 والطرق المرتبطة به:
الكائن gapi.auth2.تفويضConfig TokenClientConfig أو CodeClientConfig استبدال القديمة بأخرى جديدة
الكائن gapi.auth2.AuthorizedResponse إزالة
الكائن gapi.auth2.AuthResponse إزالة
gapi.auth2.تفويض() 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 أو استدعاء JavaScript إلى google.accounts.id.renderButton إلى تسجيل دخول المستخدم إلى حساب Google.

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

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

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

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

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

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

    {
      "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"
    }
  }