انتقال به «سرویس‌های مدیریت هویت‌سنجی Google»

نمای کلی

برای دریافت کد دسترسی به‌ازای هر کاربر برای فراخوانی Google APIs،‏ Google چندین کتابخانه جاوااسکریپت ارائه می‌دهد:

این راهنما دستورالعمل‌هایی برای انتقال از این کتابخانه‌ها به کتابخانه سرویس‌های هویتی Google ارائه می‌دهد.

با دنبال کردن این راهنما:

  • «کتابخانه پلاتفرم» منسوخ‌شده را با کتابخانه «سرویس‌های هویتی» جایگزین کنید، و
  • اگر از «کتابخانه کارخواه API» استفاده می‌کنید، واحد gapi.auth2 منسوخ‌شده، روش‌ها، و اشیای آن را بردارید و آن‌ها را با معادل‌های «سرویس‌های هویت» جایگزین کنید.

برای شرح آنچه در کتابخانه جاوا اسکریپت «سرویس‌های هویتی» تغییر کرده است، نمای کلی و نحوه عملکرد صدور مجوز کاربر را بخوانید تا اصطلاحات و مفاهیم کلیدی را مرور کنید.

اگر به‌دنبال اصالت‌سنجی برای ثبت‌نام و ورود به سیستم کاربر هستید، به‌جای آن انتقال از «ورود به سیستم Google» را ببینید.

شناسایی جریان مجوز

دو جریان مجوز کاربر ممکن وجود دارد: ضمنی و کد مجوز.

برنامه وب خود را بررسی کنید تا نوع جریان مجوز مورداستفاده را شناسایی کنید.

نشانه‌هایی که نشان می‌دهد برنامه وب شما از جریان ضمنی استفاده می‌کند:

  • برنامه وب شما کاملاً مبتنی بر مرورگر است و پلاتفرم پس‌زمینه‌ای ندارد.
  • کاربر باید برای فراخوانی Google API حضور داشته باشد، برنامه شما فقط از کد دسترسی استفاده می‌کند و به ژتون بازآوری نیاز ندارد.
  • برنامه وب شما apis.google.com/js/api.js را بار می‌کند.
  • پیاده‌سازی شما براساس OAuth 2.0 برای برنامه‌های وب سمت کارخواه است.
  • برنامه شما از یکی از ماژول‌های gapi.client یا gapi.auth2 موجود در کتابخانه کارخواه Google API برای JavaScript استفاده می‌کند.

نشانه‌هایی که نشان می‌دهد برنامه وب شما از جریان کد مجوز استفاده می‌کند:

  • پیاده‌سازی شما براساس موارد زیر است:

  • برنامه شما هم در مرورگر کاربر و هم در پلاتفرم زیرینه شما اجرا می‌شود.

  • پلاتفرم پسین شما میزبان نقطه پایان کد مجوز است.

  • پلاتفرم پسین شما ازجانب کاربران با Google API تماس می‌گیرد بدون اینکه نیازی به حضور آن‌ها باشد، که به آن حالت آفلاین نیز می‌گویند.

  • ژتون‌های بازآوری توسط پلاتفرم پسین شما مدیریت و ذخیره می‌شوند.

در برخی موارد، پایگاه کد شما ممکن است از هر دو جریان پشتیبانی کند.

انتخاب کردن جریان مجوزدهی

پیش‌از شروع انتقال، باید تعیین کنید که آیا ادامه دادن با جریان موجود یا اتخاذ جریانی متفاوت بهترین راه برای برآورده کردن نیازهای شما است.

برای درک تفاوت‌های کلیدی و مزایا و معایب هریک از این دو جریان، انتخاب جریان درستی‌سنجی را مرور کنید.

در اکثر موارد، جریان کد مجوز توصیه می‌شود زیرا بالاترین سطح امنیت کاربر را ارائه می‌دهد. پیاده‌سازی این جریان همچنین به پلاتفرم شما امکان می‌دهد تا عملکردهای آفلاین جدیدی را اضافه کند، مانند واکشی به‌روزرسانی‌ها برای اطلاع‌رسانی به کاربران درباره تغییرات قابل‌توجه در تقویم، عکس‌ها، و اشتراک‌هایشان.

بااستفاده از انتخابگرها، جریان صدور مجوز را انتخاب کنید.

جریان ضمنی

یک کد دسترسی برای استفاده درون مرورگر درحالی‌که کاربر حضور دارد دریافت کنید.

نمونه‌های جریان ضمنی برنامه‌های وب را قبل و بعداز انتقال به «سرویس‌های مدیریت هویت» نشان می‌دهد.

جریان کد مجوز

کد مجوز برای هر کاربر که توسط Google صادر شده است به پلاتفرم زیرینه شما ارسال می‌شود و در آنجا با کد دسترسی و ژتون بازآوری معاوضه می‌شود.

نمونه‌های جریان کد مجوز برنامه‌های وب را قبل و بعداز انتقال به «سرویس‌های هویتی» نشان می‌دهد.

در سراسر این راهنما، دستورالعمل‌های فهرست‌شده به‌صورت پررنگ را برای افزودن، برداشتن، به‌روزرسانی، یا جایگزین کردن عملکرد موجود دنبال کنید.

تغییرات در برنامه وب درون‌مرورگر شما

این بخش تغییراتی را که هنگام انتقال به کتابخانه جاوا اسکریپت «سرویس‌های هویتی Google» در برنامه وب درون مرورگرتان ایجاد خواهید کرد مرور می‌کند.

شناسایی کد تحت‌تأثیر و آزمایش

کوکی اشکال‌زدایی می‌تواند به پیدا کردن کد تحت‌تأثیرقرارگرفته و آزمایش رفتار پس‌از منسوخ شدن کمک کند.

در برنامه‌های بزرگ یا پیچیده، ممکن است پیدا کردن همه کدهای تحت‌تأثیر منسوخ شدن واحد gapi.auth2 دشوار باشد. برای ثبت استفاده فعلی از عملکردی که به‌زودی منسوخ می‌شود در کنسول، مقدار کوکی G_AUTH2_MIGRATION را روی informational تنظیم کنید. درصورت تمایل، دونقطه و سپس مقدار کلید را اضافه کنید تا در فضای ذخیره‌سازی جلسه نیز ثبت شود. پس‌از ورود به سیستم و دریافت اطلاعات کاربری، گزارش‌های جمع‌آوری‌شده را برای تجزیه‌وتحلیل بعدی به باطن ارسال یا بازبینی کنید. برای مثال، informational:showauth2use مبدأ و نشانی وب را در کلید فضای ذخیره‌سازی جلسه به‌نام showauth2use ذخیره می‌کند.

برای درستی‌سنجی رفتار برنامه وقتی‌که واحد gapi.auth2 دیگر بار نمی‌شود، مقدار کوکی G_AUTH2_MIGRATION را روی enforced تنظیم کنید. این کار امکان آزمایش رفتار پس‌از منسوخ شدن را پیش‌از تاریخ اجرا فراهم می‌کند.

مقادیر احتمالی کوکی G_AUTH2_MIGRATION:

  • enforced واحد gapi.auth2 بار نشود.
  • informational ثبت استفاده از عملکرد منسوخ‌شده در کنسول جاوااسکریپت. همچنین وقتی نام کلید اختیاری تنظیم شده باشد، در فضای ذخیره‌سازی جلسه ثبت می‌شود: informational:key-name.

برای به‌حداقل رساندن تأثیر بر کاربر، توصیه می‌شود ابتدا این کوکی را به‌صورت محلی درطول توسعه و آزمایش تنظیم کنید، سپس از آن در محیط‌های تولید استفاده کنید.

کتابخانه‌ها و پیمانه‌ها

ماژول gapi.auth2 اصالت‌سنجی کاربر را برای ورود به سیستم و جریان ضمنی برای صدور مجوز مدیریت می‌کند، این ماژول منسوخ‌شده و اشیاء و روش‌های آن را با کتابخانه «سرویس‌های هویتی Google» جایگزین کنید.

افزودن کتابخانه «سرویس‌های مدیریت هویت» به برنامه وب با گنجاندن آن در سند:

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

هرگونه نمونه بار کردن واحد auth2 بااستفاده از gapi.load('auth2', function) را بردارید.

کتابخانه «سرویس‌های هویتی Google» جایگزین استفاده از واحد gapi.auth2 می‌شود. می‌توانید با خیال راحت به استفاده از ماژول gapi.client از کتابخانه کارخواه Google API برای جاوااسکریپت ادامه دهید و از مزایای ایجاد خودکار روش‌های JS قابل‌فراخوانی از سند اکتشاف، گروه‌بندی چندین فراخوانی API، و عملکرد مدیریت CORS بهره‌مند شوید.

بیسکوئیت

مجوز کاربر نیازی به استفاده از کوکی ندارد.

برای جزئیات مربوط به نحوه استفاده اصالت‌سنجی کاربر از کوکی‌ها، به انتقال از «ورود به سیستم با Google» مراجعه کنید و برای استفاده از کوکی توسط سایر محصولات و سرویس‌های Google، به نحوه استفاده Google از کوکی‌ها مراجعه کنید.

اطلاعات کاربری

«سرویس‌های مدیریت هویت‌سنجی Google» اصالت‌سنجی و صدور مجوز کاربر را به دو عملیات مجزا تقسیم می‌کند و اطلاعات کاربری کاربر جدا است: توکن شناسه استفاده‌شده برای شناسایی کاربر جدا از توکن دسترسی استفاده‌شده برای صدور مجوز برگردانده می‌شود.

برای مشاهده این تغییرات، نمونه اطلاعات کاربری را ببینید.

جریان ضمنی

با برداشتن مدیریت نمایه کاربر از جریان‌های صدور مجوز، اصالت‌سنجی و صدور مجوز کاربر را از هم جدا کنید.

این ارجاع‌های مشتری جاوا اسکریپت «ورود به سیستم با Google» را بردارید:

روش‌ها

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

جریان کد مجوز

«سرویس‌های مدیریت هویت» اطلاعات اعتباری درون مرورگر را به کد شناسه و کد دسترسی تقسیم می‌کند. این تغییر برای اعتبارنامه‌هایی که ازطریق تماس‌های مستقیم با نقاط پایانی Google OAuth 2.0 از پلاتفرم پسین شما یا ازطریق کتابخانه‌هایی که روی سرور امنی در پلاتفرم شما اجرا می‌شوند (مانند Google APIs Node.js Client) به‌دست آمده‌اند اعمال نمی‌شود.

وضعیت جلسه

قبلاً، «ورود به سیستم با Google» به شما کمک می‌کرد وضعیت ورود به سیستم کاربر را بااستفاده از موارد زیر مدیریت کنید:

مسئولیت مدیریت وضعیت ورود به سیستم و جلسات کاربر در برنامه وب شما برعهده شما است.

این ارجاع‌های مشتری جاوا اسکریپت «ورود به سیستم با 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()

پیکربندی کارخواه

برنامه وب خود را به‌روز کنید تا یک مشتری توکن برای جریان کد ضمنی یا مجوز راه‌اندازی کنید.

این ارجاع‌های مشتری جاوا اسکریپت «ورود به سیستم با Google» را بردارید:

اشیاء:

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

روش‌ها:

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

جریان ضمنی

با دنبال کردن مثال موجود در مقداردهی اولیه مشتری کلید، شیء TokenClientConfig و فراخوانی initTokenClient() را برای پیکربندی برنامه وب خود اضافه کنید.

جایگزین کردن ارجاع‌های مشتری جاوا اسکریپت «ورود به سیستم با 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.

جریان کد مجوز

با دنبال کردن مثال موجود در مقداردهی اولیه Code Client، یک شیء CodeClientConfig و فراخوانی initCodeClient() را برای پیکربندی برنامه وب خود اضافه کنید.

هنگام جابه‌جایی از جریان ضمنی به جریان کد مجوز:

برداشتن ارجاع‌های مشتری جاوا اسکریپت «ورود به سیستم با Google»

اشیاء:

  • gapi.auth2.AuthorizeConfig

روش‌ها:

  • gapi.auth2.init()

پارامترها:

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

درخواست کد

اشاره کاربر، مثل کلیک کردن روی دکمه، درخواستی ایجاد می‌کند که منجر به برگرداندن کد دسترسی مستقیماً به مرورگر کاربر با جریان ضمنی می‌شود، یا پس‌از تبادل کد مجوز هر کاربر برای کد دسترسی و ژتون بازآوری، به پلاتفرم پسین شما برگردانده می‌شود.

جریان ضمنی

کدهای دسترسی ممکن است در مرورگر دریافت و استفاده شوند، درحالی‌که کاربر به سیستم وارد شده است و جلسه فعالی با Google دارد. برای حالت ضمنی، اشاره کاربر برای درخواست کد دسترسی لازم است، حتی اگر درخواست قبلی وجود داشته باشد.

جایگزین کردن ارجاع‌های مشتری جاوا اسکریپت «ورود به سیستم با Google»: با سرویس‌های مدیریت هویت‌سنجی Google:

روش‌ها:

  • ‫gapi.auth2.authorize() با TokenClient.requestAccessToken()
  • GoogleUser.reloadAuthResponse() با TokenClient.requestAccessToken()

پیوند یا دکمه‌ای اضافه کنید تا requestAccessToken() را فراخوانی کند و جریان تجربه کاربری بالاپر را برای درخواست کد دسترسی یا دریافت کد جدید درصورت منقضی شدن کد موجود آغاز کند.

پایگاه کدتان را به این موارد به‌روز کنید:

  • جریان کد OAuth 2.0 را با requestAccessToken() راه‌اندازی کنید.
  • بااستفاده از requestAccessToken و OverridableTokenClientConfig، از مجوزدهی افزایشی پشتیبانی کنید تا یک درخواست برای چندین دامنه را به چندین درخواست کوچک‌تر تقسیم کنید.
  • وقتی کد موجود منقضی یا لغو شد، کد جدیدی درخواست کنید.

کار کردن با چند دامنه ممکن است به تغییرات ساختاری در پایگاه کد شما نیاز داشته باشد تا دسترسی به دامنه‌ها را فقط درصورت نیاز درخواست کنید، نه همه را به‌طور هم‌زمان، این به‌عنوان مجوز افزایشی شناخته می‌شود. هر درخواست باید حاوی کمترین تعداد ممکن از دامنه‌ها باشد، و در حالت ایده‌آل یک دامنه داشته باشد. برای کسب اطلاعات بیشتر درباره نحوه به‌روزرسانی برنامه برای صدور مجوز افزایشی، به نحوه مدیریت رضایت کاربر مراجعه کنید.

وقتی کد دسترسی منقضی می‌شود، واحد gapi.auth2 به‌طور خودکار کد دسترسی جدید و معتبری برای برنامه وب شما دریافت می‌کند. برای بهبود امنیت کاربر، این فرایند بازآوری خودکار کد دسترسی توسط کتابخانه «سرویس‌های مدیریت هویت‌سنجی Google» پشتیبانی نمی‌شود. برنامه وب شما باید به‌روز شود تا بتواند کد دسترسی منقضی‌شده را شناسایی کند و کد جدیدی درخواست کند. برای اطلاعات بیشتر، به بخش «مدیریت کردن کد» مراجعه کنید.

جریان کد مجوز

پیوند یا دکمه‌ای اضافه کنید تا با requestCode() تماس بگیرید و کد مجوز را از Google درخواست کنید. برای مثال، راه‌اندازی جریان کد OAuth 2.0 را ببینید.

برای اطلاعات بیشتر درباره نحوه پاسخ دادن به کد دسترسی منقضی‌شده یا باطل‌شده، به بخش «مدیریت کد» مراجعه کنید.

مدیریت کردن کد

افزودن مدیریت خطا برای شناسایی تماس‌های ناموفق Google API هنگام استفاده از کد دسترسی منقضی‌شده یا لغوشده، و درخواست کد دسترسی جدید و معتبر.

وقتی از کد دسترسی منقضی‌شده یا لغوشده استفاده شود، میاناهای برنامه‌سازی کاربردی Google کد وضعیت HTTP 401 Unauthorized و پیام خطای invalid_token را برمی‌گردانند. برای مثال، پاسخ کد نامعتبر را ببینید.

نشان‌های منقضی‌شده

کدهای دسترسی کوتاه‌مدت هستند و اغلب فقط چند دقیقه اعتبار دارند.

ابطال کد

صاحب «حساب Google» می‌تواند در هر زمانی رضایت قبلی خود را لغو کند. با این کار، کدهای دسترسی و کدهای بازآوری موجود نامعتبر می‌شوند. ابطال ممکن است از پلاتفرم شما بااستفاده از revoke() یا ازطریق حساب Google راه‌اندازی شود.

جایگزین کردن ارجاع‌های مشتری جاوا اسکریپت «ورود به سیستم با 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» با حساب کاربری محلی موجود در پلاتفرم شما، که به کاهش حساب‌های تکراری در پلاتفرم شما کمک می‌کند.
  • وقتی حساب محلی جدیدی ایجاد می‌شود، کادرهای گفتگوی ثبت‌نام و جریان شما می‌تواند به‌وضوح از کادرهای گفتگوی اصالت‌سنجی کاربر و جریان‌ها جدا شود، که این امر تعداد مراحل لازم را کاهش می‌دهد و نرخ ریزش را بهبود می‌بخشد.

پس‌از ورود به سیستم و قبل‌از صدور کد دسترسی، کاربران باید برای دامنه‌های درخواستی با برنامه شما موافقت کنند.

پس‌از اعلام رضایت، کد دسترسی به‌همراه فهرستی از دامنه‌های تأییدشده یا ردشده توسط کاربر برگردانده می‌شود.

اجازه‌های جزئی به کاربران امکان می‌دهد تا دامنه‌های فردی را تأیید یا رد کنند. هنگام درخواست دسترسی به چند دامنه، هر دامنه به‌طور مستقل از دامنه‌های دیگر اعطا یا رد می‌شود. براساس انتخاب کاربر، برنامه‌تان به‌طور انتخابی ویژگی‌ها و عملکردهایی را که به یک گستره خاص بستگی دارند فعال می‌کند.

جریان ضمنی

جایگزین کردن ارجاع‌های مشتری جاوا اسکریپت «ورود به سیستم با Google» با سرویس‌های مدیریت هویت‌سنجی Google:

اشیاء:

  • ‫gapi.auth2.AuthorizeResponse با TokenClient.TokenResponse
  • ‫gapi.auth2.AuthResponse با TokenClient.TokenResponse

روش‌ها:

  • GoogleUser.hasGrantedScopes() با google.accounts.oauth2.hasGrantedAllScopes()
  • GoogleUser.getGrantedScopes() با google.accounts.oauth2.hasGrantedAllScopes()

برداشتن ارجاع‌های مشتری جاوا اسکریپت «ورود به سیستم با Google»:

روش‌ها:

  • GoogleUser.getAuthResponse()

با دنبال کردن این نمونه اجازه‌های ریزدانه، برنامه وب خود را با hasGrantedAllScopes() و hasGrantedAnyScope() به‌روز کنید.

جریان کد مجوز

با دنبال کردن دستورالعمل‌های مدیریت کد مجوز، نقطه پایانی کد مجوز را به پلاتفرم پسین خود به‌روزرسانی یا اضافه کنید.

پلاتفرم خود را به‌روز کنید تا مراحل شرح‌داده‌شده در راهنمای استفاده از مدل کد را برای اعتبارسنجی درخواست و دریافت کد دسترسی و کد بازآوری دنبال کنید.

با دنبال کردن دستورالعمل‌های مربوط به مجوزدهی افزایشی و بررسی گستره‌های دسترسی اعطاشده توسط کاربر، پلاتفرم خود را به‌روز کنید تا ویژگی‌ها و عملکردها را براساس گستره‌های فردی که کاربر تأیید کرده است به‌طور انتخابی فعال یا غیرفعال کنید.

نمونه‌های جریان ضمنی

روش قدیمی

کتابخانه کارخواه GAPI

نمونه‌ای از کتابخانه کارخواه Google API برای جاوا اسکریپت که در مرورگر بااستفاده از کادر گفتگوی بالاپر برای رضایت کاربر اجرا می‌شود.

واحد 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>

کتابخانه کارخواه جاوااسکریپت

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 Google Cloud 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 the Google authorization 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 the Google authorization 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>

روش جدید

فقط GIS

این مثال فقط کتابخانه جاوا اسکریپت «سرویس‌های هویتی Google» را نشان می‌دهد که از مدل کد و کادر گفتگوی بالاپر برای کسب رضایت کاربر استفاده می‌کند. این راهنما برای نشان دادن حداقل مراحل لازم برای پیکربندی کارخواه، درخواست و دریافت کد دسترسی، و فراخوانی Google API ارائه شده است.

<!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» را بااستفاده از مدل کد اضافه کنید، مدول gapi.auth2 را بردارید، و بااستفاده از کتابخانه کارخواه Google API برای جاوااسکریپت با میانای برنامه‌سازی کاربردی تماس بگیرید.

از Promises،‏ async، و await برای اعمال ترتیب بار کردن کتابخانه و گرفتن و امتحان مجدد خطاهای مجوز استفاده می‌شود. فراخوان میانای برنامه‌سازی کاربردی فقط پس‌از دردسترس بودن کد دسترسی معتبر انجام می‌شود.

انتظار می‌رود کاربران وقتی کد دسترسی وجود ندارد، دکمه «نمایش تقویم» را فشار دهند وقتی صفحه برای اولین‌بار بار می‌شود، یا بعداز اینکه کد دسترسی منقضی شده است.

<!DOCTYPE html>
<html>
<head>
    <title>GAPI and GIS Example</title>
    <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="gisLoad()"></script>
</head>
<body>
    <h1>GAPI Client with GIS Authorization</h1>
    <button id="authorizeBtn" style="visibility:hidden;">Authorize and Load Events</button>
    <button id="revokeBtn" style="visibility:hidden;">Revoke Access</button>
    <div id="content"></div>

    <script>
        const YOUR_CLIENT_ID = "YOUR_CLIENT_ID";
        const YOUR_API_KEY = 'YOUR_API_KEY';
        const CALENDAR_SCOPE = 'https://www.googleapis.com/auth/calendar.readonly';

        let tokenClient;
        let libsLoaded = 0;

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

        async function initGapiClient() {
            try {
                await gapi.client.init({ apiKey: YOUR_API_KEY });
                await gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
                console.log('GAPI client initialized.');
                checkAllLoaded();
            } catch (err) {
                handleError('GAPI initialization failed:', err);
            }
        }

        function gisLoad() {
            try {
                tokenClient = google.accounts.oauth2.initTokenClient({
                    client_id: YOUR_CLIENT_ID,
                    scope: CALENDAR_SCOPE,
                    callback: '', // Will be set dynamically
                    error_callback: handleGisError,
                });
                console.log('GIS TokenClient initialized.');
                checkAllLoaded();
            } catch (err) {
                handleError('GIS initialization failed:', err);
            }
        }

        function checkAllLoaded() {
            libsLoaded++;
            if (libsLoaded === 2) {
                document.getElementById('authorizeBtn').style.visibility = 'visible';
                document.getElementById('revokeBtn').style.visibility = 'visible';
                document.getElementById('authorizeBtn').onclick = makeApiCall;
                document.getElementById('revokeBtn').onclick = revokeAccess;
                console.log('Ready to authorize.');
            }
        }

        function handleGisError(err) {
            console.error('GIS Error:', err);
            let message = 'An error occurred during authorization.';
            if (err && err.type === 'popup_failed_to_open') {
                message = 'Failed to open popup. Please disable popup blockers.';
            } else if (err && err.type === 'popup_closed') {
                message = 'Authorization popup was closed.';
            }
            document.getElementById('content').textContent = message;
        }

        function handleError(message, error) {
            console.error(message, error);
            document.getElementById('content').textContent = `${message} ${error.message || JSON.stringify(error)}`;
        }

        async function makeApiCall() {
            document.getElementById('content').textContent = 'Processing...';
            try {
                let token = gapi.client.getToken();
                if (!token || !token.access_token) {
                    console.log('No token, fetching one...');
                    await getToken();
                }

                console.log('Calling Calendar API...');
                const response = await gapi.client.calendar.events.list({ 'calendarId': 'primary' });
                displayEvents(response.result);
            } catch (err) {
                console.error('API call failed:', err);
                const errorInfo = err.result && err.result.error;
                if (errorInfo && (errorInfo.code === 401 || (errorInfo.code === 403 && errorInfo.status === "PERMISSION_DENIED"))) {
                    console.log('Auth error on API call, refreshing token...');
                    try {
                        await getToken({ prompt: 'consent' }); // Force refresh
                        const retryResponse = await gapi.client.calendar.events.list({ 'calendarId': 'primary' });
                        displayEvents(retryResponse.result);
                    } catch (refreshErr) {
                        handleError('Failed to refresh token or retry API call:', refreshErr);
                    }
                } else {
                    handleError('Error loading events:', err.result ? err.result.error : err);
                }
            }
        }

        async function getToken(options = { prompt: '' }) {
            return new Promise((resolve, reject) => {
                if (!tokenClient) return reject(new Error("GIS TokenClient not initialized."));
                tokenClient.callback = (tokenResponse) => {
                    if (tokenResponse.error) {
                        reject(new Error(`Token Error: ${tokenResponse.error} - ${tokenResponse.error_description}`));
                    } else {
                        console.log('Token acquired.');
                        resolve(tokenResponse);
                    }
                };
                tokenClient.requestAccessToken(options);
            });
        }

        function displayEvents(result) {
            const events = result.items;
            if (events && events.length > 0) {
                let eventList = '<h3>Upcoming Events:</h3><ul>' + events.map(event =>
                    `<li>${event.summary} (${event.start.dateTime || event.start.date})</li>`
                ).join('') + '</ul>';
                document.getElementById('content').innerHTML = eventList;
            } else {
                document.getElementById('content').textContent = 'No upcoming events found.';
            }
        }

        function revokeAccess() {
            const token = gapi.client.getToken();
            if (token && token.access_token) {
                google.accounts.oauth2.revoke(token.access_token, () => {
                    console.log('Access revoked.');
                    document.getElementById('content').textContent = 'Access has been revoked.';
                    gapi.client.setToken(null);
                });
            } else {
                document.getElementById('content').textContent = 'No token to revoke.';
            }
        }
    </script>
</body>
</html>

فراخوانی GAPI

این مثال نشان می‌دهد که چگونه کتابخانه «سرویس‌های مدیریت هویت‌سنجی Google» را بااستفاده از مدل کد اضافه کنید، مدول gapi.auth2 را بردارید، و بااستفاده از کتابخانه کارخواه Google API برای جاوااسکریپت با میانای برنامه‌سازی کاربردی تماس بگیرید.

از متغیرها برای اعمال ترتیب بار کردن کتابخانه استفاده می‌شود. تماس‌های GAPI از درون فراخوانی برگشتی پس‌از برگرداندن کد دسترسی معتبر برقرار می‌شوند.

انتظار می‌رود کاربران وقتی صفحه برای اولین‌بار بار می‌شود و دوباره وقتی می‌خواهند اطلاعات «تقویم» خود را بازآوری کنند، دکمه «نمایش تقویم» را فشار دهند.

<!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» می‌تواند از هدایت نشانی وب برای برگرداندن کد مجوز مستقیماً به نقطه پایانی کد پشتیبان شما استفاده کند، یا از رسیدگی‌کننده بازخوانی جاوا اسکریپت که در مرورگر کاربر اجرا می‌شود و پاسخ را به پلاتفرم شما پروکسی می‌کند. در هر دو مورد، پلاتفرم پسین شما جریان 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 the Google authorization 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();
}

روش جدید

تجربه کاربری بالاپر سرویس‌های مدیریت هویت Google

این مثال فقط کتابخانه جاوا اسکریپت «سرویس‌های هویتی Google» را نشان می‌دهد که از مدل کد مجوز، کادر گفتگوی بالاپر برای رضایت کاربر، و رسیدگی‌کننده بازخوانی برای دریافت کد مجوز از 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>

تجربه کاربری هدایت سرویس‌های مدیریت هویت 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 \
                  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>

کتابخانه‌های جاوا اسکریپت

سرویس‌های مدیریت هویت‌سنجی Google یک کتابخانه جاوا اسکریپت واحد است که برای اصالت‌سنجی و صدور مجوز کاربر استفاده می‌شود و ویژگی‌ها و عملکردهای موجود در چندین کتابخانه و ماژول مختلف را ادغام و جایگزین می‌کند:

کنش‌هایی که باید هنگام انتقال به «سرویس‌های مدیریت هویت» انجام دهید:

کتابخانه جاوااسکریپت موجود کتابخانه جاوااسکریپت جدید یادداشت‌ها
apis.google.com/js/api.js accounts.google.com/gsi/client کتابخانه جدیدی اضافه کنید و جریان ضمنی را دنبال کنید.
apis.google.com/js/client.js accounts.google.com/gsi/client کتابخانه جدیدی اضافه کنید و جریان کد مجوز را دنبال کنید.

مرجع سریع کتابخانه

مقایسه شیء و روش بین کتابخانه کارخواه جاوا اسکریپت ورود به سیستم با Google قدیمی و کتابخانه سرویس‌های هویتی Google جدید و یادداشت‌ها با اطلاعات بیشتر و اقداماتی که باید درطول انتقال انجام شود.

قدیمی جدید یادداشت‌ها
شیء 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() 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() یا requestAccessToken() جایگزین کردن قدیمی با جدید
gapi.auth2.ClientConfig() ‫TokenClientConfig یا CodeClientConfig جایگزین کردن قدیمی با جدید
gapi.auth2.getAuthInstance() برداشتن
gapi.auth2.init() ‫initTokenClient() یا initCodeClient() جایگزین کردن قدیمی با جدید
‫gapi.auth2.OfflineAccessOptions شیء برداشتن
‫gapi.auth2.SignInOptions شیء برداشتن
شیء gapi.signin2 و روش‌های مرتبط:
gapi.signin2.render() برداشتن بار کردن HTML DOM عنصر g_id_signin یا فراخوانی JS به google.accounts.id.renderButton باعث می‌شود کاربر به سیستم «حساب Google» وارد شود.

اطلاعات اعتباری نمونه

اعتبارنامه‌های موجود

کتابخانه پلاتفرم ورود به سیستم Google، کتابخانه کارخواه Google API برای JavaScript، یا تماس‌های مستقیم با نقاط پایانی Google OAuth 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»

کتابخانه سرویس‌های هویتی 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 هنگام تلاش برای ایجاد درخواست API بااستفاده از کد دسترسی منقضی‌شده، لغوشده، یا نامعتبر:

سرایندهای پاسخ 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"
    }
  }