OAuth 2.0 برای برنامه های کاربردی وب سمت مشتری

این سند نحوه پیاده‌سازی مجوز OAuth 2.0 برای دسترسی به APIهای گوگل از یک برنامه وب جاوا اسکریپت را توضیح می‌دهد. OAuth 2.0 به کاربران اجازه می‌دهد داده‌های خاصی را با یک برنامه به اشتراک بگذارند، در حالی که نام کاربری، رمز عبور و سایر اطلاعات آنها خصوصی باقی می‌ماند. به عنوان مثال، یک برنامه می‌تواند از OAuth 2.0 برای دریافت مجوز از کاربران برای ذخیره فایل‌ها در Google Drives آنها استفاده کند.

این جریان OAuth 2.0، جریان اعطای ضمنی نامیده می‌شود. این جریان برای برنامه‌هایی طراحی شده است که فقط در صورت حضور کاربر در برنامه به APIها دسترسی دارند. این برنامه‌ها قادر به ذخیره اطلاعات محرمانه نیستند.

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

کتابخانه کلاینت APIهای گوگل و سرویس‌های هویت گوگل

اگر از کتابخانه کلاینت APIهای گوگل برای جاوا اسکریپت جهت برقراری تماس‌های مجاز با گوگل استفاده می‌کنید، باید از کتابخانه جاوا اسکریپت Google Identity Services برای مدیریت جریان OAuth 2.0 استفاده کنید. لطفاً به مدل توکن سرویس‌های هویت گوگل مراجعه کنید که مبتنی بر جریان اعطای ضمنی OAuth 2.0 است.

پیش‌نیازها

فعال کردن APIها برای پروژه شما

هر برنامه‌ای که APIهای گوگل را فراخوانی می‌کند، باید آن APIها را در ... فعال کند. API Console.

برای فعال کردن API برای پروژه خود:

  1. Open the API Library در Google API Console.
  2. If prompted, select a project, or create a new one.
  3. API Library تمام APIهای موجود را که بر اساس خانواده محصول و محبوبیت گروه‌بندی شده‌اند، فهرست می‌کند. اگر API مورد نظر برای فعال‌سازی در لیست قابل مشاهده نیست، از جستجو برای یافتن آن استفاده کنید یا روی مشاهده همه در خانواده محصولی که به آن تعلق دارد کلیک کنید.
  4. API مورد نظر خود را انتخاب کنید و سپس روی دکمه‌ی فعال‌سازی کلیک کنید.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

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

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

  1. Go to the Clients page.
  2. روی ایجاد کلاینت کلیک کنید.
  3. نوع برنامه کاربردی وب را انتخاب کنید.
  4. فرم را تکمیل کنید. برنامه‌هایی که از جاوا اسکریپت برای ارسال درخواست‌های مجاز Google API استفاده می‌کنند، باید مبدأهای مجاز جاوا اسکریپت را مشخص کنند. مبدأها، دامنه‌هایی را مشخص می‌کنند که برنامه شما می‌تواند از آنها درخواست‌ها را به سرور OAuth 2.0 ارسال کند. این مبدأها باید از قوانین اعتبارسنجی گوگل پیروی کنند.

شناسایی محدوده‌های دسترسی

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

قبل از شروع پیاده‌سازی احراز هویت OAuth 2.0، توصیه می‌کنیم محدوده‌هایی را که برنامه شما برای دسترسی به آنها نیاز به مجوز دارد، شناسایی کنید.

سند OAuth 2.0 API Scopes شامل لیست کاملی از scopeهایی است که ممکن است برای دسترسی به APIهای گوگل از آنها استفاده کنید.

دریافت توکن‌های دسترسی OAuth 2.0

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

مرحله ۱: هدایت به سرور OAuth 2.0 گوگل

برای درخواست اجازه دسترسی به داده‌های یک کاربر، کاربر را به سرور OAuth 2.0 گوگل هدایت کنید.

نقاط پایانی OAuth 2.0

یک URL برای درخواست دسترسی از نقطه پایانی OAuth 2.0 گوگل در https://accounts.google.com/o/oauth2/v2/auth ایجاد کنید. این نقطه پایانی از طریق HTTPS قابل دسترسی است؛ اتصالات HTTP ساده رد می‌شوند.

سرور احراز هویت گوگل از پارامترهای رشته پرس و جوی زیر برای برنامه‌های وب سرور پشتیبانی می‌کند:

پارامترها
client_id مورد نیاز

شناسه کلاینت برای برنامه شما. می‌توانید این مقدار را در Cloud ConsoleClients page.

redirect_uri مورد نیاز

تعیین می‌کند که سرور API پس از تکمیل جریان مجوز توسط کاربر، کاربر را به کجا هدایت کند. مقدار باید دقیقاً با یکی از URI های هدایت مجاز برای کلاینت OAuth 2.0 که در کلاینت خود پیکربندی کرده‌اید، مطابقت داشته باشد. Cloud ConsoleClients pageاگر این مقدار با یک URI تغییر مسیر مجاز برای client_id ارائه شده مطابقت نداشته باشد، خطای redirect_uri_mismatch دریافت خواهید کرد.

توجه داشته باشید که طرح http یا https ، بزرگی و کوچکی حروف و اسلش انتهایی (' / ') باید همگی مطابقت داشته باشند.

response_type مورد نیاز

برنامه‌های جاوا اسکریپت باید مقدار پارامتر را token تنظیم کنند. این مقدار به سرور احراز هویت گوگل دستور می‌دهد که توکن دسترسی را به صورت یک جفت name=value در شناسه قطعه URI ( # ) که کاربر پس از تکمیل فرآیند احراز هویت به آن هدایت می‌شود، برگرداند.

scope مورد نیاز

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

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

توصیه می‌کنیم برنامه شما در صورت امکان، درخواست دسترسی به حوزه‌های مجوز را در context ارائه دهد. با درخواست دسترسی به داده‌های کاربر در context، با استفاده از مجوز افزایشی ، به کاربران کمک می‌کنید تا بفهمند که چرا برنامه شما به دسترسی مورد درخواست خود نیاز دارد.

state توصیه شده

هر مقدار رشته‌ای را که برنامه شما برای حفظ وضعیت بین درخواست مجوز شما و پاسخ سرور مجوز استفاده می‌کند، مشخص می‌کند. سرور پس از اینکه کاربر درخواست دسترسی برنامه شما را تأیید یا رد کرد، مقدار دقیقی را که شما به عنوان یک جفت name=value در شناسه قطعه URL ( # ) از redirect_uri ارسال می‌کنید، برمی‌گرداند.

شما می‌توانید از این پارامتر برای چندین هدف استفاده کنید، مانند هدایت کاربر به منبع صحیح در برنامه‌تان، ارسال nonceها و کاهش جعل درخواست بین سایتی. از آنجایی که redirect_uri شما قابل حدس زدن است، استفاده از مقدار state می‌تواند اطمینان شما را از اینکه اتصال ورودی نتیجه یک درخواست احراز هویت است، افزایش دهد. اگر یک رشته تصادفی ایجاد کنید یا هش یک کوکی یا مقدار دیگری را که وضعیت کلاینت را ثبت می‌کند، کدگذاری کنید، می‌توانید پاسخ را اعتبارسنجی کنید تا علاوه بر این، اطمینان حاصل شود که درخواست و پاسخ از یک مرورگر سرچشمه گرفته‌اند و در برابر حملاتی مانند جعل درخواست بین سایتی محافظت ایجاد کنید. برای مثالی از نحوه ایجاد و تأیید یک توکن state ، به مستندات OpenID Connect مراجعه کنید.

include_granted_scopes اختیاری

برنامه‌ها را قادر می‌سازد تا از مجوز افزایشی برای درخواست دسترسی به حوزه‌های اضافی در متن استفاده کنند. اگر مقدار این پارامتر را روی true تنظیم کنید و درخواست مجوز اعطا شود، توکن دسترسی جدید، هر حوزه‌ای را که کاربر قبلاً به برنامه دسترسی داده است، پوشش می‌دهد. برای مثال‌ها به بخش مجوز افزایشی مراجعه کنید.

login_hint اختیاری

اگر برنامه شما بداند کدام کاربر در حال تلاش برای احراز هویت است، می‌تواند از این پارامتر برای ارائه یک راهنما به سرور احراز هویت گوگل استفاده کند. سرور از این راهنما برای ساده‌سازی جریان ورود به سیستم، یا با پر کردن فیلد ایمیل در فرم ورود به سیستم یا با انتخاب جلسه ورود چندگانه مناسب، استفاده می‌کند.

مقدار پارامتر را روی یک آدرس ایمیل یا شناسه sub تنظیم کنید، که معادل شناسه گوگل کاربر است.

prompt اختیاری

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

مقادیر ممکن عبارتند از:

none هیچ صفحه احراز هویت یا رضایتی نمایش داده نشود. نباید با مقادیر دیگری مشخص شود.
consent از کاربر رضایت‌نامه دریافت کنید.
select_account از کاربر بخواهید یک حساب کاربری انتخاب کند.

نمونه تغییر مسیر به سرور مجوز گوگل

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

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

پس از ایجاد URL درخواست، کاربر را به آن هدایت کنید.

نمونه کد جاوا اسکریپت

قطعه کد جاوا اسکریپت زیر نحوه شروع جریان مجوزدهی در جاوا اسکریپت را بدون استفاده از کتابخانه کلاینت APIهای گوگل برای جاوا اسکریپت نشان می‌دهد. از آنجایی که این نقطه پایانی OAuth 2.0 از اشتراک‌گذاری منابع بین مبدا (CORS) پشتیبانی نمی‌کند، این قطعه کد فرمی ایجاد می‌کند که درخواست را به آن نقطه پایانی باز می‌کند.

/*
 * 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 <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_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.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();
}

مرحله ۲: گوگل از کاربر رضایت می‌خواهد

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

برنامه شما در این مرحله نیازی به انجام کاری ندارد، زیرا منتظر پاسخ از سرور OAuth 2.0 گوگل است که نشان می‌دهد آیا دسترسی اعطا شده است یا خیر. این پاسخ در مرحله بعد توضیح داده شده است.

خطاها

درخواست‌ها به نقطه پایانی احراز هویت OAuth 2.0 گوگل ممکن است به جای جریان‌های احراز هویت و مجوز مورد انتظار، پیام‌های خطای کاربرپسند را نمایش دهند. کدهای خطای رایج و راه‌حل‌های پیشنهادی عبارتند از:

admin_policy_enforced

حساب گوگل به دلیل سیاست‌های مدیر Google Workspace خود قادر به تأیید یک یا چند محدوده درخواستی نیست. برای اطلاعات بیشتر در مورد اینکه چگونه یک مدیر می‌تواند دسترسی به همه محدوده‌ها یا محدوده‌های حساس و محدود شده را تا زمانی که دسترسی به طور صریح به شناسه کلاینت OAuth شما اعطا نشده باشد، محدود کند، به مقاله راهنمای مدیریت Google Workspace با عنوان «کنترل دسترسی برنامه‌های شخص ثالث و داخلی به داده‌های Google Workspace» مراجعه کنید.

disallowed_useragent

نقطه پایانی احراز هویت درون یک عامل کاربری تعبیه‌شده نمایش داده می‌شود که توسط سیاست‌های OAuth 2.0 گوگل مجاز نیست.

توسعه‌دهندگان iOS و macOS ممکن است هنگام باز کردن درخواست‌های مجوز در WKWebView با این خطا مواجه شوند. توسعه‌دهندگان باید به جای آن از کتابخانه‌های iOS مانند Google Sign-In برای iOS یا OpenID Foundation’s AppAuth برای iOS استفاده کنند.

توسعه‌دهندگان وب ممکن است زمانی که یک برنامه iOS یا macOS یک لینک وب عمومی را در یک عامل کاربر تعبیه‌شده باز می‌کند و کاربر از سایت شما به نقطه پایانی مجوز OAuth 2.0 گوگل هدایت می‌شود، با این خطا مواجه شوند. توسعه‌دهندگان باید اجازه دهند لینک‌های عمومی در کنترل‌کننده لینک پیش‌فرض سیستم عامل، که شامل کنترل‌کننده‌های لینک جهانی یا برنامه مرورگر پیش‌فرض است، باز شوند. کتابخانه SFSafariViewController نیز یک گزینه پشتیبانی شده است.

org_internal

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

invalid_client

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

deleted_client

کلاینت OAuth که برای ایجاد درخواست استفاده شده بود، حذف شده است. حذف می‌تواند به صورت دستی یا خودکار در مورد کلاینت‌های بلااستفاده انجام شود. کلاینت‌های حذف شده را می‌توان ظرف 30 روز از زمان حذف بازیابی کرد. اطلاعات بیشتر .

invalid_grant

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

origin_mismatch

ممکن است طرح، دامنه و/یا پورت جاوا اسکریپتی که درخواست مجوز از آن ارسال شده است، با یک URI مجاز جاوا اسکریپت ثبت شده برای شناسه کلاینت OAuth مطابقت نداشته باشد. منابع مجاز جاوا اسکریپت را در Google Cloud ConsoleClients page.

redirect_uri_mismatch

redirect_uri ارسال شده در درخواست مجوز با یک URI تغییر مسیر مجاز برای شناسه کلاینت OAuth مطابقت ندارد. URI های تغییر مسیر مجاز را در Google Cloud ConsoleClients page.

ممکن است طرح، دامنه و/یا پورت جاوا اسکریپتی که درخواست مجوز از آن ارسال شده است، با یک URI مجاز جاوا اسکریپت ثبت شده برای شناسه کلاینت OAuth مطابقت نداشته باشد. منابع مجاز جاوا اسکریپت را در Google Cloud ConsoleClients page.

پارامتر redirect_uri ممکن است به جریان OAuth out-of-band (OOB) اشاره داشته باشد که منسوخ شده و دیگر پشتیبانی نمی‌شود. برای به‌روزرسانی ادغام خود به راهنمای مهاجرت مراجعه کنید.

invalid_request

درخواستی که ارائه دادید، مشکلی داشت. این مشکل می‌تواند به دلایل مختلفی باشد:

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

مرحله ۳: مدیریت پاسخ سرور OAuth 2.0

نقاط پایانی OAuth 2.0

سرور OAuth 2.0 پاسخی به redirect_uri مشخص شده در درخواست توکن دسترسی شما ارسال می‌کند.

اگر کاربر درخواست را تأیید کند، پاسخ حاوی یک توکن دسترسی است. اگر کاربر درخواست را تأیید نکند، پاسخ حاوی یک پیام خطا است. توکن دسترسی یا پیام خطا، همانطور که در زیر نشان داده شده است، روی قطعه هش URI ریدایرکت بازگردانده می‌شود:

  • پاسخ یک توکن دسترسی:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    علاوه بر پارامتر access_token ، رشته fragment همچنین شامل پارامتر token_type است که همیشه روی Bearer تنظیم می‌شود و پارامتر expires_in که طول عمر توکن را بر حسب ثانیه مشخص می‌کند. اگر پارامتر state در درخواست access token مشخص شده باشد، مقدار آن نیز در پاسخ گنجانده می‌شود.

  • پاسخ یک خطا:
    https://oauth2.example.com/callback#error=access_denied

نمونه پاسخ سرور OAuth 2.0

شما می‌توانید این جریان را با کلیک روی نمونه URL زیر که دسترسی فقط خواندنی برای مشاهده فراداده‌های فایل‌های گوگل درایو شما و دسترسی فقط خواندنی برای مشاهده رویدادهای تقویم گوگل شما را درخواست می‌کند، آزمایش کنید:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

پس از تکمیل جریان OAuth 2.0، به http://localhost/oauth2callback هدایت خواهید شد. این URL خطای 404 NOT FOUND را نشان می‌دهد، مگر اینکه دستگاه محلی شما اتفاقاً فایلی را در آن آدرس ارائه دهد. مرحله بعدی جزئیات بیشتری در مورد اطلاعات برگردانده شده در URI هنگام هدایت مجدد کاربر به برنامه شما ارائه می‌دهد.

مرحله ۴: بررسی کنید که کاربران کدام حوزه‌ها را اعطا کرده‌اند

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

با این حال، استثنائاتی نیز وجود دارد. برنامه‌های Google Workspace Enterprise با تفویض اختیار در سطح دامنه یا برنامه‌هایی که به عنوان Trusted علامت‌گذاری شده‌اند، صفحه رضایت مجوزهای جزئی را دور می‌زنند. برای این برنامه‌ها، کاربران صفحه رضایت مجوزهای جزئی را نمی‌بینند. در عوض، برنامه شما یا همه محدوده‌های درخواستی را دریافت می‌کند یا هیچ کدام را دریافت نمی‌کند.

برای اطلاعات بیشتر، به نحوه مدیریت مجوزهای جزئی مراجعه کنید.

نقاط پایانی OAuth 2.0

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

برای مثال، نمونه پاسخ توکن دسترسی زیر نشان می‌دهد که کاربر به برنامه شما دسترسی به مجوزهای فعالیت Drive فقط خواندنی و رویدادهای Calendar را اعطا کرده است:

  {
    "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
    "expires_in": 3920,
    "token_type": "Bearer",
    "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
    "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
  }

فراخوانی API های گوگل

نقاط پایانی OAuth 2.0

پس از اینکه برنامه شما یک توکن دسترسی دریافت کرد، می‌توانید از این توکن برای برقراری تماس با یک API گوگل از طرف یک حساب کاربری مشخص استفاده کنید، البته اگر دامنه(های) دسترسی مورد نیاز API اعطا شده باشد. برای انجام این کار، توکن دسترسی را با وارد کردن پارامتر پرس‌وجوی access_token یا مقدار Bearer هدر HTTP Authorization ، در درخواست به API قرار دهید. در صورت امکان، هدر HTTP ترجیح داده می‌شود، زیرا رشته‌های پرس‌وجو معمولاً در گزارش‌های سرور قابل مشاهده هستند. در بیشتر موارد، می‌توانید از یک کتابخانه کلاینت برای تنظیم تماس‌های خود با APIهای گوگل استفاده کنید (برای مثال، هنگام فراخوانی API فایل‌های درایو ).

شما می‌توانید تمام APIهای گوگل را امتحان کنید و حوزه‌های کاربرد آنها را در OAuth 2.0 Playground مشاهده کنید.

مثال‌های HTTP GET

فراخوانی نقطه پایانی drive.files (رابط برنامه‌نویسی کاربردی Drive Files) با استفاده از هدر HTTP مربوط به Authorization: Bearer ممکن است چیزی شبیه به شکل زیر باشد. توجه داشته باشید که باید توکن دسترسی خودتان را مشخص کنید:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

در اینجا فراخوانی همان API برای کاربر احراز هویت شده با استفاده از پارامتر رشته پرس و جوی access_token مشاهده می‌کنید:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

مثال‌های curl

می‌توانید این دستورات را با برنامه خط فرمان curl آزمایش کنید. در اینجا مثالی آورده شده است که از گزینه هدر HTTP (ترجیحاً) استفاده می‌کند:

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

یا، به طور جایگزین، گزینه پارامتر رشته پرس و جو:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

نمونه کد جاوا اسکریپت

قطعه کد زیر نحوه استفاده از CORS (اشتراک‌گذاری منابع بین‌منبعی) را برای ارسال درخواست به API گوگل نشان می‌دهد. این مثال از کتابخانه کلاینت APIهای گوگل برای جاوا اسکریپت استفاده نمی‌کند. با این حال، حتی اگر از کتابخانه کلاینت استفاده نمی‌کنید، راهنمای پشتیبانی CORS در مستندات آن کتابخانه احتمالاً به شما در درک بهتر این درخواست‌ها کمک خواهد کرد.

در این قطعه کد، متغیر access_token نشان دهنده توکنی است که شما برای ارسال درخواست‌های API از طرف کاربر مجاز دریافت کرده‌اید. مثال کامل نحوه ذخیره آن توکن در حافظه محلی مرورگر و بازیابی آن هنگام ارسال درخواست API را نشان می‌دهد.

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) {
  console.log(xhr.response);
};
xhr.send(null);

مثال کامل

نقاط پایانی OAuth 2.0

این نمونه کد نحوه تکمیل جریان OAuth 2.0 را در جاوا اسکریپت بدون استفاده از کتابخانه کلاینت APIهای گوگل برای جاوا اسکریپت نشان می‌دهد. این کد برای یک صفحه HTML است که دکمه‌ای را برای امتحان کردن یک درخواست API نمایش می‌دهد. اگر روی دکمه کلیک کنید، کد بررسی می‌کند که آیا صفحه، توکن دسترسی API را در حافظه محلی مرورگر شما ذخیره کرده است یا خیر. در صورت وجود، درخواست API را اجرا می‌کند. در غیر این صورت، جریان OAuth 2.0 را آغاز می‌کند.

برای جریان OAuth 2.0، صفحه این مراحل را دنبال می‌کند:

  1. این کاربر را به سرور OAuth 2.0 گوگل هدایت می‌کند که درخواست دسترسی به حوزه‌های https://www.googleapis.com/auth/drive.metadata.readonly و https://www.googleapis.com/auth/calendar.readonly را دارد.
  2. پس از اعطای (یا رد) دسترسی به یک یا چند محدوده درخواستی، کاربر به صفحه اصلی هدایت می‌شود که توکن دسترسی را از رشته شناسه قطعه تجزیه می‌کند.
  3. این صفحه بررسی می‌کند که کاربر به کدام حوزه‌ها (scope) دسترسی به برنامه را اعطا کرده است.
  4. اگر کاربر به scope()های درخواستی دسترسی داده باشد، صفحه از توکن دسترسی برای ارسال درخواست API نمونه استفاده می‌کند.

    درخواست API، متد about.get از API درایو را فراخوانی می‌کند تا اطلاعات مربوط به حساب گوگل درایو کاربر مجاز را بازیابی کند.

  5. اگر درخواست با موفقیت اجرا شود، پاسخ API در کنسول اشکال‌زدایی مرورگر ثبت می‌شود.

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

برای اجرای این کد به صورت محلی، باید مقادیری را برای متغیرهای YOUR_CLIENT_ID و YOUR_REDIRECT_URI تنظیم کنید که با اعتبارنامه‌های مجوز شما مطابقت داشته باشند. متغیر YOUR_REDIRECT_URI باید روی همان URL که صفحه در آن نمایش داده می‌شود تنظیم شود. این مقدار باید دقیقاً با یکی از URI های تغییر مسیر مجاز برای کلاینت OAuth 2.0 که در ... پیکربندی کرده‌اید، مطابقت داشته باشد. Cloud ConsoleClients pageاگر این مقدار با یک URI مجاز مطابقت نداشته باشد، خطای redirect_uri_mismatch دریافت خواهید کرد. پروژه شما همچنین باید API مناسب برای این درخواست را فعال کرده باشد.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';

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

      trySampleRequest();
    } else {
      console.log('State mismatch. Possible CSRF attack');
    }
  }

  // Function to generate a random state value
  function generateCryptoRandomState() {
    const randomValues = new Uint32Array(2);
    window.crypto.getRandomValues(randomValues);

    // Encode as UTF-8
    const utf8Encoder = new TextEncoder();
    const utf8Array = utf8Encoder.encode(
      String.fromCharCode.apply(null, randomValues)
    );

    // Base64 encode the UTF-8 data
    return btoa(String.fromCharCode.apply(null, utf8Array))
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=+$/, '');
  }

  // 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']) { 
      // User authorized the request. Now, check which scopes were granted.
      if (params['scope'].includes('https://www.googleapis.com/auth/drive.metadata.readonly')) {
        // User authorized read-only Drive activity permission.
        // Calling the APIs, etc.
        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 {
        // User didn't authorize read-only Drive activity permission.
        // Update UX and application accordingly
        console.log('User did not authorize read-only Drive activity permission.');
      }

      // Check if user authorized Calendar read permission.
      if (params['scope'].includes('https://www.googleapis.com/auth/calendar.readonly')) {
        // User authorized Calendar read permission.
        // Calling the APIs, etc.
        console.log('User authorized Calendar read permission.');
      }
      else {
        // User didn't authorize Calendar read permission.
        // Update UX and application accordingly
        console.log('User did not authorize Calendar read permission.');
      } 
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // create random state value and store in local storage
    var state = generateCryptoRandomState();
    localStorage.setItem('state', state);

    // 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 https://www.googleapis.com/auth/calendar.readonly',
                  'state': state,
                  '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>

قوانین اعتبارسنجی مبدأ جاوا اسکریپت

گوگل قوانین اعتبارسنجی زیر را برای جاوا اسکریپت اعمال می‌کند تا به توسعه‌دهندگان کمک کند برنامه‌های خود را ایمن نگه دارند. جاوا اسکریپت شما باید از این قوانین پیروی کند. برای تعریف دامنه، میزبان و طرحواره که در زیر ذکر شده است، به بخش ۳ RFC 3986 مراجعه کنید.

قوانین اعتبارسنجی
طرح

ریشه‌های جاوا اسکریپت باید از طرح HTTPS استفاده کنند، نه HTTP ساده. URI های میزبان محلی (از جمله URI های آدرس IP میزبان محلی) از این قانون معاف هستند.

میزبان

میزبان‌ها نمی‌توانند آدرس‌های IP خام باشند. آدرس‌های IP میزبان محلی از این قانون مستثنی هستند.

دامنه
  • دامنه‌های سطح بالای میزبان (TLD) باید به فهرست پسوندهای عمومی تعلق داشته باشند.
  • دامنه‌های میزبان نمی‌توانند “googleusercontent.com” باشند.
  • کدهای جاوا اسکریپت نمی‌توانند شامل دامنه‌های کوتاه‌کننده‌ی آدرس اینترنتی (مثلاً goo.gl ) باشند، مگر اینکه برنامه مالک دامنه باشد.
  • اطلاعات کاربری

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

    مسیر

    ریشه‌های جاوا اسکریپت نمی‌توانند شامل مؤلفه مسیر باشند.

    پرس و جو

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

    قطعه

    ریشه‌های جاوا اسکریپت نمی‌توانند شامل کامپوننت fragment باشند.

    شخصیت‌ها ریشه‌های جاوا اسکریپت نمی‌توانند شامل کاراکترهای خاصی از جمله موارد زیر باشند:
    • کاراکترهای وایلدکارت ( '*' )
    • کاراکترهای ASCII غیرقابل چاپ
    • کدگذاری‌های درصدی نامعتبر (هر کدگذاری درصدی که از فرم کدگذاری URL شامل علامت درصد و به دنبال آن دو رقم هگزادسیمال پیروی نکند)
    • کاراکترهای تهی (یک کاراکتر تهی کدگذاری شده، مانند %00 ، %C0%80 )

    مجوز افزایشی

    در پروتکل OAuth 2.0، برنامه شما برای دسترسی به منابعی که توسط scopeها مشخص می‌شوند، درخواست مجوز می‌کند. درخواست مجوز برای منابع در زمانی که به آنها نیاز دارید، بهترین روش برای تجربه کاربری محسوب می‌شود. برای فعال کردن این روش، سرور احراز هویت گوگل از احراز هویت افزایشی پشتیبانی می‌کند. این ویژگی به شما امکان می‌دهد scopeها را در صورت نیاز درخواست کنید و اگر کاربر مجوز scope جدید را اعطا کند، یک کد احراز هویت را برمی‌گرداند که می‌تواند با توکنی حاوی تمام scopeهایی که کاربر به پروژه اعطا کرده است، مبادله شود.

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

    در این حالت، در زمان ورود به سیستم، برنامه ممکن است برای انجام ورود اولیه، دامنه‌های openid و profile را درخواست کند و سپس بعداً در زمان اولین درخواست برای ذخیره یک ترکیب، دامنه https://www.googleapis.com/auth/drive.file را درخواست کند.

    قوانین زیر در مورد توکن دسترسی که از طریق مجوز افزایشی به دست می‌آید، اعمال می‌شود:

    • این توکن می‌تواند برای دسترسی به منابع مربوط به هر یک از حوزه‌های موجود در مجوز ترکیبی جدید استفاده شود.
    • وقتی از توکن به‌روزرسانی برای مجوز ترکیبی جهت دریافت توکن دسترسی استفاده می‌کنید، توکن دسترسی نشان‌دهنده مجوز ترکیبی است و می‌تواند برای هر یک از مقادیر scope موجود در پاسخ استفاده شود.
    • مجوز ترکیبی شامل تمام حوزه‌هایی است که کاربر به پروژه API اعطا کرده است، حتی اگر این مجوزها از کلاینت‌های مختلف درخواست شده باشند. به عنوان مثال، اگر کاربری با استفاده از کلاینت دسکتاپ یک برنامه، دسترسی به یک حوزه را اعطا کند و سپس از طریق یک کلاینت موبایل، حوزه دیگری را به همان برنامه اعطا کند، مجوز ترکیبی شامل هر دو حوزه خواهد بود.
    • اگر توکنی را که نشان‌دهنده‌ی یک مجوز ترکیبی است، لغو کنید، دسترسی به تمام حوزه‌های آن مجوز از طرف کاربر مرتبط به‌طور همزمان لغو می‌شود.

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

    نقاط پایانی OAuth 2.0

    برای افزودن محدوده‌ها به یک توکن دسترسی موجود، پارامتر include_granted_scopes را در درخواست خود به سرور OAuth 2.0 گوگل وارد کنید.

    قطعه کد زیر نحوه انجام این کار را نشان می‌دهد. این قطعه کد فرض می‌کند که شما محدوده‌هایی را که توکن دسترسی شما برای آنها معتبر است، در حافظه محلی مرورگر ذخیره کرده‌اید. (کد کامل مثال با تنظیم ویژگی oauth2-test-params.scope در حافظه محلی مرورگر، فهرستی از محدوده‌هایی را که توکن دسترسی برای آنها معتبر است، ذخیره می‌کند.)

    این قطعه کد، محدوده‌هایی را که توکن دسترسی برای آنها معتبر است با محدوده‌ای که می‌خواهید برای یک پرس‌وجوی خاص استفاده کنید، مقایسه می‌کند. اگر توکن دسترسی آن محدوده را پوشش ندهد، جریان OAuth 2.0 شروع می‌شود. در اینجا، تابع oauth2SignIn همان تابعی است که در مرحله ۲ ارائه شد (و بعداً در مثال کامل ارائه می‌شود).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    ابطال توکن

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

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

    نقاط پایانی OAuth 2.0

    برای لغو یک توکن از طریق برنامه‌نویسی، برنامه شما درخواستی به https://oauth2.googleapis.com/revoke ارسال می‌کند و توکن را به عنوان پارامتر وارد می‌کند:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    این توکن می‌تواند یک توکن دسترسی یا یک توکن به‌روزرسانی باشد. اگر توکن، توکن دسترسی باشد و یک توکن به‌روزرسانی متناظر داشته باشد، توکن به‌روزرسانی نیز لغو خواهد شد.

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

    قطعه کد جاوا اسکریپت زیر نحوه لغو یک توکن در جاوا اسکریپت را بدون استفاده از کتابخانه کلاینت APIهای گوگل برای جاوا اسکریپت نشان می‌دهد. از آنجایی که نقطه پایانی OAuth 2.0 گوگل برای لغو توکن‌ها از اشتراک‌گذاری منابع بین‌منبعی (CORS) پشتیبانی نمی‌کند، کد به جای استفاده از متد XMLHttpRequest() برای ارسال درخواست، یک فرم ایجاد کرده و فرم را به نقطه پایانی ارسال می‌کند.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }

    پیاده‌سازی حفاظت از حساب‌های کاربری متقابل

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

    برخی از نمونه‌های انواع رویدادهایی که توسط سرویس حفاظت از حساب‌های کاربری متقابل گوگل به برنامه شما ارسال می‌شوند عبارتند از:

    • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
    • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
    • https://schemas.openid.net/secevent/risc/event-type/account-disabled

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