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

نظرة عامة

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

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

يؤدي اتباع هذا الدليل إلى:

  • استبدل مكتبة النظام الأساسي التي تم إيقافها نهائيًا بمكتبة خدمات الهوية،
  • في حال استخدام "مكتبة برامج واجهة برمجة التطبيقات"، أزِل وحدة 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.

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

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

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

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

بسكويت

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

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

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

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

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

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

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

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

الطُرق

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

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

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

حالة الجلسة

في السابق، ساعدك "تسجيل الدخول بحساب 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 Identity Services:

العناصر:

  • ‫"gapi.auth2.AuthorizeConfig" مع "TokenClientConfig"

الطُرق:

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

المَعلمات:

  • gapi.auth2.AuthorizeConfig.login_hint مع TokenClientConfig.login_hint.
  • gapi.auth2.GoogleUser.getHostedDomain() مع TokenClientConfig.hd.

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

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

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

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

العناصر:

  • gapi.auth2.AuthorizeConfig

الطُرق:

  • gapi.auth2.init()

المَعلمات:

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

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

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

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

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

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

الطُرق:

  • ‫"gapi.auth2.authorize()" مع "TokenClient.requestAccessToken()"
  • GoogleUser.reloadAuthResponse() مع TokenClient.requestAccessToken()

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

عدِّل قاعدة الرموز لتنفيذ ما يلي:

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

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

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

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

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

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

التعامل مع الرمز المميّز

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

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

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

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

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

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

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

الطُرق:

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

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

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

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

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

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

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

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

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

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

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

استبدِل مراجع عميل JavaScript لتسجيل الدخول بحساب Google بخدمات Google Identity Services:

العناصر:

  • ‫"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 async/await

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

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

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