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

این سند توضیح می‌دهد که چگونه برنامه‌های وب سرور از Google API Client Libraries یا Google OAuth 2.0 برای اجرای مجوز OAuth 2.0 برای دسترسی به YouTube Analytics API یا YouTube Reporting API استفاده می‌کنند.

OAuth 2.0 به کاربران اجازه می دهد تا داده های خاصی را با یک برنامه به اشتراک بگذارند در حالی که نام کاربری، رمز عبور و سایر اطلاعات خود را خصوصی نگه می دارند. به عنوان مثال، یک برنامه می تواند از OAuth 2.0 برای دریافت مجوز برای بازیابی داده های YouTube Analytics یک کانال استفاده کند.

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

برنامه‌های کاربردی وب سرور اغلب از حساب‌های سرویس برای تأیید درخواست‌های API استفاده می‌کنند، به‌ویژه زمانی که برای دسترسی به داده‌های مبتنی بر پروژه به‌جای داده‌های خاص کاربر، API‌های Cloud را فراخوانی می‌کنند. برنامه های کاربردی وب سرور می توانند از حساب های خدماتی در ارتباط با مجوز کاربر استفاده کنند.

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

کتابخانه های مشتری

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

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

کتابخانه های Google API Client برای برنامه های سمت سرور برای زبان های زیر در دسترس هستند:

پیش نیازها

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

هر برنامه‌ای که Google 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 YouTube Analytics و YouTube Reporting API استفاده کنید. بسیاری از برنامه‌هایی که داده‌های YouTube Analytics را بازیابی می‌کنند، با YouTube Data API نیز ارتباط دارند. هر API دیگری را که برنامه شما از آن استفاده می کند پیدا کنید و آن ها را نیز فعال کنید.

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

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

  1. Go to the Credentials page.
  2. روی ایجاد اعتبار > شناسه مشتری OAuth کلیک کنید.
  3. نوع برنامه کاربردی وب را انتخاب کنید.
  4. فرم را پر کنید و روی ایجاد کلیک کنید. برنامه هایی که از زبان ها و فریم ورک هایی مانند PHP، جاوا، پایتون، روبی و دات نت استفاده می کنند باید URI های مجاز تغییر مسیر را مشخص کنند. URI های تغییر مسیر، نقاط پایانی هستند که سرور OAuth 2.0 می تواند پاسخ ها را به آنها ارسال کند. این نقاط پایانی باید از قوانین اعتبارسنجی Google پیروی کنند.

    برای آزمایش، می توانید URI هایی را مشخص کنید که به ماشین محلی اشاره می کنند، مانند http://localhost:8080 . با در نظر گرفتن این موضوع، لطفاً توجه داشته باشید که همه نمونه‌های این سند از http://localhost:8080 به عنوان URI تغییر مسیر استفاده می‌کنند.

    توصیه می کنیم نقاط پایانی تأیید اعتبار برنامه خود را طوری طراحی کنید که برنامه شما کدهای مجوز را در معرض سایر منابع موجود در صفحه قرار ندهد.

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

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

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

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

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

YouTube Analytics API از حوزه های زیر استفاده می کند:

محدوده ها
https://www.googleapis.com/auth/youtube حساب YouTube خود را مدیریت کنید
https://www.googleapis.com/auth/youtube.readonly حساب YouTube خود را مشاهده کنید
https://www.googleapis.com/auth/youtubepartner دارایی ها و محتوای مرتبط خود را در YouTube مشاهده و مدیریت کنید
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/youtube حساب YouTube خود را مدیریت کنید
https://www.googleapis.com/auth/youtube.readonly حساب YouTube خود را مشاهده کنید
https://www.googleapis.com/auth/youtubepartner دارایی ها و محتوای مرتبط خود را در YouTube مشاهده و مدیریت کنید
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/youtube حساب YouTube خود را مدیریت کنید
https://www.googleapis.com/auth/youtube.readonly حساب YouTube خود را مشاهده کنید
https://www.googleapis.com/auth/youtubepartner دارایی ها و محتوای مرتبط خود را در YouTube مشاهده و مدیریت کنید
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/youtube حساب YouTube خود را مدیریت کنید
https://www.googleapis.com/auth/youtube.readonly حساب YouTube خود را مشاهده کنید
https://www.googleapis.com/auth/youtubepartner دارایی ها و محتوای مرتبط خود را در YouTube مشاهده و مدیریت کنید
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید

YouTube Reporting API از حوزه های زیر استفاده می کند:

محدوده ها
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید

سند OAuth 2.0 API Scopes حاوی فهرست کاملی از حوزه‌هایی است که ممکن است برای دسترسی به Google API از آنها استفاده کنید.

الزامات خاص زبان

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

PHP

برای اجرای نمونه کدهای PHP در این سند، به موارد زیر نیاز دارید:

  • PHP 8.0 یا بالاتر با رابط خط فرمان (CLI) و پسوند JSON نصب شده است.
  • ابزار مدیریت وابستگی Composer .
  • Google APIs Client Library برای PHP:

    composer require google/apiclient:^2.15.0

برای اطلاعات بیشتر به کتابخانه سرویس گیرنده Google APIs برای PHP مراجعه کنید.

پایتون

برای اجرای نمونه کدهای پایتون در این سند، به موارد زیر نیاز دارید:

  • پایتون 3.7 یا بالاتر
  • ابزار مدیریت بسته پیپ .
  • کتابخانه سرویس گیرنده Google APIs برای نسخه 2.0 پایتون:
    pip install --upgrade google-api-python-client
  • google-auth ، google-auth-oauthlib و google-auth-httplib2 برای مجوز کاربر.
    pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
  • چارچوب برنامه وب Flask Python.
    pip install --upgrade flask
  • کتابخانه HTTP requests
    pip install --upgrade requests

اگر نمی‌توانید پایتون و راهنمای مهاجرت مرتبط را ارتقا دهید، یادداشت انتشار کتابخانه کلاینت Google API Python را مرور کنید.

روبی

برای اجرای نمونه کد روبی در این سند، به موارد زیر نیاز دارید:

  • روبی 2.6 یا بالاتر
  • کتابخانه Google Auth برای روبی:

    gem install googleauth
  • کتابخانه های سرویس گیرنده برای Drive و Calendar Google API:

    gem install google-apis-drive_v3 google-apis-calendar_v3
  • چارچوب برنامه وب سیناترا روبی.

    gem install sinatra

Node.js

برای اجرای نمونه کد Node.js در این سند، به موارد زیر نیاز دارید:

  • LTS تعمیر و نگهداری، LTS فعال یا نسخه فعلی Node.js.
  • Google APIs Node.js Client:

    npm install googleapis crypto express express-session

HTTP/REST

برای اینکه بتوانید مستقیماً با نقاط پایانی OAuth 2.0 تماس بگیرید، نیازی به نصب هیچ کتابخانه ای ندارید.

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

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

لیست زیر به سرعت این مراحل را خلاصه می کند:

  1. برنامه شما مجوزهای مورد نیاز خود را شناسایی می کند.
  2. برنامه شما کاربر را به همراه لیست مجوزهای درخواستی به Google هدایت می کند.
  3. کاربر تصمیم می گیرد که آیا مجوزها را به برنامه شما اعطا کند یا خیر.
  4. برنامه شما متوجه می شود که کاربر چه تصمیمی گرفته است.
  5. اگر کاربر مجوزهای درخواستی را اعطا کرده باشد، برنامه شما نشانه های مورد نیاز برای درخواست های API را از طرف کاربر بازیابی می کند.

مرحله 1: پارامترهای مجوز را تنظیم کنید

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

  • اگر از کتابخانه سرویس گیرنده Google برای احراز هویت و مجوز OAuth 2.0 استفاده می کنید، شیئی را ایجاد و پیکربندی می کنید که این پارامترها را تعریف می کند.
  • اگر مستقیماً با نقطه پایانی Google OAuth 2.0 تماس بگیرید، یک URL ایجاد می‌کنید و پارامترها را روی آن URL تنظیم می‌کنید.

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

PHP

قطعه کد زیر یک شی Google\Client() ایجاد می کند که پارامترهای درخواست مجوز را تعریف می کند.

آن شی از اطلاعات فایل client_secret.json شما برای شناسایی برنامه شما استفاده می کند. (برای اطلاعات بیشتر درباره آن فایل، به ایجاد اعتبارنامه مجوز مراجعه کنید.) شی همچنین محدوده هایی را که برنامه شما برای دسترسی به آنها درخواست مجوز می کند و نشانی اینترنتی نقطه پایانی تأیید برنامه شما را شناسایی می کند، که پاسخ سرور OAuth 2.0 Google را مدیریت می کند. در نهایت، کد پارامترهای access_type اختیاری و include_granted_scopes تنظیم می کند.

به عنوان مثال، برای درخواست دسترسی آفلاین برای بازیابی گزارش‌های YouTube Analytics کاربر:

use Google\Client;

$client = new Client();

// Required, call the setAuthConfig function to load authorization credentials from
// client_secret.json file.
$client->setAuthConfig('client_secret.json');

// Required, to set the scope value, call the addScope function
$client->addScope(Google_Service_YouTubeAnalytics::YT_ANALYTICS_READONLY);

// Required, call the setRedirectUri function to specify a valid redirect URI for the
// provided client_id
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');

// Recommended, offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');

// Recommended, call the setState function. Using a state value can increase your assurance that
// an incoming connection is the result of an authentication request.
$client->setState($sample_passthrough_value);

// Optional, if your application knows which user is trying to authenticate, it can use this
// parameter to provide a hint to the Google Authentication Server.
$client->setLoginHint('hint@example.com');

// Optional, call the setPrompt function to set "consent" will prompt the user for consent
$client->setPrompt('consent');

// Optional, call the setIncludeGrantedScopes function with true to enable incremental
// authorization
$client->setIncludeGrantedScopes(true);

پایتون

قطعه کد زیر از ماژول google-auth-oauthlib.flow برای ساخت درخواست مجوز استفاده می کند.

کد یک شی Flow می سازد که برنامه شما را با استفاده از اطلاعات فایل client_secret.json که پس از ایجاد اعتبارنامه های مجوز دانلود کرده اید شناسایی می کند. این شیء همچنین محدوده‌هایی را که برنامه شما برای دسترسی به آنها درخواست مجوز می‌کند و نشانی اینترنتی نقطه پایانی تأیید برنامه شما را مشخص می‌کند، که پاسخ سرور OAuth 2.0 Google را مدیریت می‌کند. در نهایت، کد پارامترهای access_type اختیاری و include_granted_scopes تنظیم می کند.

به عنوان مثال، برای درخواست دسترسی آفلاین برای بازیابی گزارش‌های YouTube Analytics کاربر:

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Required, call the from_client_secrets_file method to retrieve the client ID from a
# client_secret.json file. The client ID (from that file) and access scopes are required. (You can
# also use the from_client_config method, which passes the client configuration as it originally
# appeared in a client secrets file but doesn't access the file itself.)
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file('client_secret.json',
    scopes=['https://www.googleapis.com/auth/yt-analytics.readonly',
            'https://www.googleapis.com/auth/calendar.readonly'])

# Required, indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
flow.redirect_uri = 'https://www.example.com/oauth2callback'

# Generate URL for request to Google's OAuth 2.0 server.
# Use kwargs to set optional request parameters.
authorization_url, state = flow.authorization_url(
    # Recommended, enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type='offline',
    # Optional, enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true',
    # Optional, if your application knows which user is trying to authenticate, it can use this
    # parameter to provide a hint to the Google Authentication Server.
    login_hint='hint@example.com',
    # Optional, set prompt to 'consent' will prompt the user for consent
    prompt='consent')

روبی

از فایل client_secrets.json که ایجاد کرده اید برای پیکربندی یک شی کلاینت در برنامه خود استفاده کنید. هنگامی که یک شی کلاینت را پیکربندی می‌کنید، دامنه‌هایی را که برنامه شما باید به آن دسترسی داشته باشد، به همراه URL به نقطه پایانی تأیید برنامه خود، که پاسخ سرور OAuth 2.0 را مدیریت می‌کند، مشخص می‌کنید.

به عنوان مثال، برای درخواست دسترسی آفلاین برای بازیابی گزارش‌های YouTube Analytics کاربر:

require 'googleauth'
require 'googleauth/web_user_authorizer'
require 'googleauth/stores/redis_token_store'

require 'google/apis/youtube_analytics_v1'
require 'google/apis/calendar_v3'

# Required, call the from_file method to retrieve the client ID from a
# client_secret.json file.
client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')

# Required, scope value 
# Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
         'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']

# Required, Authorizers require a storage instance to manage long term persistence of
# access and refresh tokens.
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)

# Required, indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
callback_uri = '/oauth2callback'

# To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
# from the client_secret.json file. To get these credentials for your application, visit
# https://console.cloud.google.com/apis/credentials.
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope,
                                                token_store, callback_uri)

برنامه شما از شی کلاینت برای انجام عملیات OAuth 2.0 استفاده می کند، مانند ایجاد URL های درخواست مجوز و اعمال نشانه های دسترسی به درخواست های HTTP.

Node.js

قطعه کد زیر یک شی google.auth.OAuth2 ایجاد می کند که پارامترهای درخواست مجوز را تعریف می کند.

آن شی از اطلاعات فایل client_secret.json شما برای شناسایی برنامه شما استفاده می کند. برای درخواست مجوز از کاربر برای بازیابی رمز دسترسی، آنها را به صفحه رضایت هدایت می کنید. برای ایجاد URL صفحه رضایت:

const {google} = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
 * from the client_secret.json file. To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
const scopes = [
  'https://www.googleapis.com/auth/yt-analytics.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a secure random state value.
const state = crypto.randomBytes(32).toString('hex');

// Store state in the session
req.session.state = state;

// Generate a url that asks permissions for the Drive activity and Google Calendar scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true,
  // Include the state parameter to reduce the risk of CSRF attacks.
  state: state
});

نکته مهم - refresh_token فقط در اولین مجوز بازگردانده می شود. جزئیات بیشتر در اینجا .

HTTP/REST

نقطه پایانی OAuth 2.0 Google در https://accounts.google.com/o/oauth2/v2/auth است. این نقطه پایانی فقط از طریق HTTPS قابل دسترسی است. اتصالات HTTP ساده رد می شود.

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

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

شناسه مشتری برای برنامه شما. شما می توانید این مقدار را در API ConsoleCredentials page.

redirect_uri مورد نیاز

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

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

response_type مورد نیاز

تعیین می کند که آیا نقطه پایانی Google OAuth 2.0 یک کد مجوز را برمی گرداند یا خیر.

مقدار پارامتر را برای code برنامه های وب سرور تنظیم کنید.

scope مورد نیاز

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

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

YouTube Analytics API از حوزه های زیر استفاده می کند:

محدوده ها
https://www.googleapis.com/auth/youtube حساب YouTube خود را مدیریت کنید
https://www.googleapis.com/auth/youtube.readonly حساب YouTube خود را مشاهده کنید
https://www.googleapis.com/auth/youtubepartner دارایی ها و محتوای مرتبط خود را در YouTube مشاهده و مدیریت کنید
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/youtube حساب YouTube خود را مدیریت کنید
https://www.googleapis.com/auth/youtube.readonly حساب YouTube خود را مشاهده کنید
https://www.googleapis.com/auth/youtubepartner دارایی ها و محتوای مرتبط خود را در YouTube مشاهده و مدیریت کنید
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/youtube حساب YouTube خود را مدیریت کنید
https://www.googleapis.com/auth/youtube.readonly حساب YouTube خود را مشاهده کنید
https://www.googleapis.com/auth/youtubepartner دارایی ها و محتوای مرتبط خود را در YouTube مشاهده و مدیریت کنید
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/youtube حساب YouTube خود را مدیریت کنید
https://www.googleapis.com/auth/youtube.readonly حساب YouTube خود را مشاهده کنید
https://www.googleapis.com/auth/youtubepartner دارایی ها و محتوای مرتبط خود را در YouTube مشاهده و مدیریت کنید
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید

YouTube Reporting API از حوزه های زیر استفاده می کند:

محدوده ها
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
،
محدوده ها
https://www.googleapis.com/auth/yt-analytics-monetary.readonly گزارش های پولی و غیر پولی YouTube Analytics را برای محتوای YouTube خود مشاهده کنید
https://www.googleapis.com/auth/yt-analytics.readonly گزارش‌های YouTube Analytics را برای محتوای YouTube خود مشاهده کنید

سند OAuth 2.0 API Scopes فهرست کاملی از حوزه هایی را ارائه می دهد که ممکن است برای دسترسی به Google API از آنها استفاده کنید.

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

access_type توصیه می شود

نشان می دهد که آیا برنامه شما می تواند نشانه های دسترسی را در زمانی که کاربر در مرورگر حضور ندارد بازخوانی کند یا خیر. مقادیر پارامترهای معتبر online هستند که مقدار پیش‌فرض است و offline .

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

state توصیه می شود

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

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

include_granted_scopes اختیاری

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

login_hint اختیاری

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

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

prompt اختیاری

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

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

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

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

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

PHP

  1. یک URL برای درخواست دسترسی از سرور OAuth 2.0 Google ایجاد کنید:
    $auth_url = $client->createAuthUrl();
  2. کاربر را به $auth_url هدایت کنید:
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

پایتون

این مثال نحوه هدایت کاربر را به URL مجوز با استفاده از چارچوب برنامه وب Flask نشان می دهد:

return flask.redirect(authorization_url)

روبی

  1. یک URL برای درخواست دسترسی از سرور OAuth 2.0 Google ایجاد کنید:
    auth_uri = authorizer.get_authorization_url(request: request)
  2. کاربر را به auth_uri هدایت کنید.

Node.js

  1. برای درخواست دسترسی از سرور OAuth 2.0، از URL authorizationUrl ایجاد شده از روش generateAuthUrl مرحله 1 استفاده کنید.
  2. کاربر را به authorizationUrl هدایت کنید.
    res.redirect(authorizationUrl);

HTTP/REST

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

نشانی اینترنتی نمونه زیر درخواست دسترسی آفلاین ( access_type=offline ) به محدوده‌ای را می‌دهد که اجازه دسترسی برای بازیابی گزارش‌های YouTube Analytics کاربر را می‌دهد. از مجوز افزایشی استفاده می‌کند تا اطمینان حاصل کند که رمز دسترسی جدید هر حوزه‌ای را که کاربر قبلاً به برنامه دسترسی داده است را پوشش می‌دهد. URL همچنین مقادیر لازم را برای پارامترهای redirect_uri ، response_type و client_id و همچنین برای پارامتر state تنظیم می کند. URL حاوی خطوط شکسته و فاصله برای خوانایی است.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly&
 access_type=offline&
 include_granted_scopes=true&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 response_type=code&
 client_id=client_id

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

سرور OAuth 2.0 Google کاربر را احراز هویت می کند و از کاربر رضایت می گیرد تا برنامه شما به محدوده های درخواستی دسترسی پیدا کند. پاسخ با استفاده از URL تغییر مسیری که مشخص کرده اید به برنامه شما ارسال می شود.

مرحله 3: گوگل رضایت کاربر را درخواست می کند

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

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

خطاها

درخواست‌ها به نقطه پایانی مجوز OAuth 2.0 Google ممکن است پیام‌های خطای کاربر را به‌جای جریان‌های احراز هویت و مجوز مورد انتظار نمایش دهند. کدهای خطای رایج و راهکارهای پیشنهادی در زیر فهرست شده‌اند.

admin_policy_enforced

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

disallowed_useragent

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

اندروید

برنامه‌نویسان Android ممکن است هنگام باز کردن درخواست‌های مجوز در android.webkit.WebView با این پیام خطا مواجه شوند. توسعه‌دهندگان باید در عوض از کتابخانه‌های Android مانند Google Sign-In برای Android یا OpenID Foundation's AppAuth for Android استفاده کنند.

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

iOS

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

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

org_internal

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

invalid_client

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

invalid_grant

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

redirect_uri_mismatch

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

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

invalid_request

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

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

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

سرور OAuth 2.0 با استفاده از URL مشخص شده در درخواست به درخواست دسترسی برنامه شما پاسخ می دهد.

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

یک پاسخ خطا:

https://oauth2.example.com/auth?error=access_denied

پاسخ کد مجوز:

https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7

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

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

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly&
 access_type=offline&
 include_granted_scopes=true&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 response_type=code&
 client_id=client_id

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

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

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

PHP

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

$access_token = $client->fetchAccessTokenWithAuthCode($_GET['code']);

پایتون

در صفحه پاسخ به تماس خود، از کتابخانه google-auth برای تأیید پاسخ سرور مجوز استفاده کنید. سپس، از روش flow.fetch_token برای مبادله کد مجوز در آن پاسخ برای یک نشانه دسترسی استفاده کنید:

state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/yt-analytics.readonly'],
    state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)

# Store the credentials in the session.
# ACTION ITEM for developers:
#     Store user's access and refresh tokens in your data store if
#     incorporating this code into your real app.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'token_uri': credentials.token_uri,
    'client_id': credentials.client_id,
    'client_secret': credentials.client_secret,
    'granted_scopes': credentials.granted_scopes}

روبی

در صفحه پاسخ به تماس خود، از کتابخانه googleauth برای تأیید پاسخ سرور مجوز استفاده کنید. از روش authorizer.handle_auth_callback_deferred برای ذخیره کد مجوز استفاده کنید و به آدرس اینترنتی که در ابتدا درخواست مجوز کرده بود، برگردید. این امر با ذخیره موقت نتایج در جلسه کاربر، تبادل کد را به تعویق می اندازد.

  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url

Node.js

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

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
app.get('/oauth2callback', async (req, res) => {
  let q = url.parse(req.url, true).query;

  if (q.error) { // An error response e.g. error=access_denied
    console.log('Error:' + q.error);
  } else if (q.state !== req.session.state) { //check state value
    console.log('State mismatch. Possible CSRF attack');
    res.end('State mismatch. Possible CSRF attack');
  } else { // Get access and refresh tokens (if access_type is offline)

    let { tokens } = await oauth2Client.getToken(q.code);
    oauth2Client.setCredentials(tokens);
});

HTTP/REST

برای تبادل کد مجوز برای یک نشانه دسترسی، با https://oauth2.googleapis.com/token endpoint تماس بگیرید و پارامترهای زیر را تنظیم کنید:

فیلدها
client_id شناسه مشتری به دست آمده از API ConsoleCredentials page.
client_secret راز مشتری به دست آمده از API ConsoleCredentials page.
code کد مجوز از درخواست اولیه بازگردانده شد.
grant_type همانطور که در مشخصات OAuth 2.0 تعریف شده است ، مقدار این فیلد باید روی authorization_code تنظیم شود.
redirect_uri یکی از URI های تغییر مسیر که برای پروژه شما در فهرست فهرست شده است API ConsoleCredentials page برای client_id داده شده.

قطعه زیر یک نمونه درخواست را نشان می دهد:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

Google به این درخواست با برگرداندن یک شی JSON که حاوی یک نشانه دسترسی کوتاه مدت و یک نشانه تازه‌سازی است، پاسخ می‌دهد. توجه داشته باشید که رمز تازه‌سازی تنها در صورتی برگردانده می‌شود که برنامه شما در درخواست اولیه سرور مجوز Google، پارامتر access_type را روی offline تنظیم کند.

پاسخ شامل فیلدهای زیر است:

فیلدها
access_token رمزی که برنامه شما برای تأیید درخواست Google API ارسال می کند.
expires_in طول عمر باقیمانده رمز دسترسی در ثانیه.
refresh_token توکنی که می توانید از آن برای به دست آوردن یک نشانه دسترسی جدید استفاده کنید. نشانه‌های Refresh تا زمانی که کاربر دسترسی را لغو نکند معتبر هستند. باز هم، این فیلد تنها در صورتی در این پاسخ وجود دارد که در درخواست اولیه به سرور مجوز Google، پارامتر access_type را روی offline تنظیم کنید.
scope دامنه دسترسی اعطا شده توسط access_token به صورت لیستی از رشته های حساس به حروف کوچک و کوچک با فاصله بیان می شود.
token_type نوع رمز برگشتی. در این زمان، مقدار این فیلد همیشه روی Bearer تنظیم می شود.

قطعه زیر یک نمونه پاسخ را نشان می دهد:

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

خطاها

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

invalid_grant

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

مرحله 6: بررسی کنید که کاربران چه محدوده هایی را اعطا کرده اند

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

PHP

برای بررسی اینکه کاربر کدام حوزه را اعطا کرده است، از متد getGrantedScope() استفاده کنید:

// Space-separated string of granted scopes if it exists, otherwise null.
$granted_scopes = $client->getOAuth2Service()->getGrantedScope();

// Determine which scopes user granted and build a dictionary
$granted_scopes_dict = [
  'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
  'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
];

پایتون

شیء credentials برگشتی دارای ویژگی granted_scopes است که لیستی از دامنه هایی است که کاربر به برنامه شما اعطا کرده است.

credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'token_uri': credentials.token_uri,
    'client_id': credentials.client_id,
    'client_secret': credentials.client_secret,
    'granted_scopes': credentials.granted_scopes}

تابع زیر بررسی می‌کند که کاربر کدام حوزه را به برنامه شما اعطا کرده است.

def check_granted_scopes(credentials):
  features = {}
  if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']:
    features['drive'] = True
  else:
    features['drive'] = False

  if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']:
    features['calendar'] = True
  else:
    features['calendar'] = False

  return features

روبی

هنگام درخواست چندین دامنه به طور همزمان، بررسی کنید که کدام محدوده از طریق ویژگی scope شی credentials اعطا شده است.

# User authorized the request. Now, check which scopes were granted.
if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)
  # User authorized read-only Drive activity permission.
  # Calling the APIs, etc
else
  # User didn't authorize read-only Drive activity permission.
  # Update UX and application accordingly
end

# Check if user authorized Calendar read permission.
if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)
  # User authorized Calendar read permission.
  # Calling the APIs, etc.
else
  # User didn't authorize Calendar read permission.
  # Update UX and application accordingly
end

Node.js

هنگام درخواست چندین دامنه به طور همزمان، بررسی کنید که کدام محدوده از طریق ویژگی scope شی tokens اعطا شده است.

// User authorized the request. Now, check which scopes were granted.
if (tokens.scope.includes('https://www.googleapis.com/auth/yt-analytics.readonly'))
{
  // User authorized read-only Drive activity permission.
  // Calling the APIs, etc.
}
else
{
  // User didn't authorize read-only Drive activity permission.
  // Update UX and application accordingly
}

// Check if user authorized Calendar read permission.
if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
{
  // User authorized Calendar read permission.
  // Calling the APIs, etc.
}
else
{
  // User didn't authorize Calendar read permission.
  // Update UX and application accordingly
}

HTTP/REST

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

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

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

با Google API تماس بگیرید

PHP

با انجام مراحل زیر از کد دسترسی برای فراخوانی APIهای Google استفاده کنید:

  1. اگر نیاز به اعمال یک نشانه دسترسی به یک شی جدید Google\Client دارید - برای مثال، اگر نشانه دسترسی را در یک جلسه کاربر ذخیره کرده اید - از روش setAccessToken استفاده کنید:
    $client->setAccessToken($access_token);
  2. یک شیء سرویس برای API که می خواهید فراخوانی کنید بسازید. شما با ارائه یک شیء مجاز Google\Client به سازنده برای API که می خواهید فراخوانی کنید، یک شیء سرویس می سازید. به عنوان مثال، برای فراخوانی YouTube Analytics API:
    $youtube = new Google_Service_YouTubeAnalytics($client);
  3. با استفاده از رابط ارائه شده توسط شی سرویس، درخواست هایی را به سرویس API ارسال کنید. به عنوان مثال، برای بازیابی گزارش YouTube Analytics برای کانال کاربر تأیید شده:
    $report = $youtube->reports->query('channel==MINE', '2016-05-01', '2016-06-30', 'views');

پایتون

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

  1. یک شیء سرویس برای API که می خواهید فراخوانی کنید بسازید. شما با فراخوانی روش build کتابخانه googleapiclient.discovery با نام و نسخه API و اعتبار کاربر، یک شیء سرویس می‌سازید: به عنوان مثال، برای فراخوانی نسخه 1 YouTube Analytics API:
    from googleapiclient.discovery import build
    
    youtube = build('youtubeAnalytics', 'v1', credentials=credentials)
  2. با استفاده از رابط ارائه شده توسط شی سرویس، درخواست هایی را به سرویس API ارسال کنید. به عنوان مثال، برای بازیابی گزارش YouTube Analytics برای کانال کاربر تأیید شده:
    report = youtube.reports().query(ids='channel==MINE', start_date='2016-05-01', end_date='2016-06-30', metrics='views').execute()

روبی

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

  1. یک شیء سرویس برای API که می خواهید فراخوانی کنید بسازید. به عنوان مثال، برای تماس با نسخه 1 YouTube Analytics API:
    youtube = Google::Apis::YoutubeAnalyticsV1::YouTubeAnalyticsService.new
  2. اعتبارنامه را روی سرویس تنظیم کنید:
    youtube.authorization = credentials
  3. با استفاده از رابط ارائه شده توسط شی سرویس، درخواست هایی را به سرویس API ارسال کنید. به عنوان مثال، برای بازیابی گزارش YouTube Analytics برای کانال کاربر تأیید شده:
    report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views')

متناوباً، مجوز می‌تواند بر اساس هر روش با ارائه پارامتر options به یک روش ارائه شود:

report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views', options: { authorization: auth_client })

Node.js

پس از به دست آوردن یک نشانه دسترسی و تنظیم آن بر روی شی OAuth2 ، از شی برای فراخوانی API های Google استفاده کنید. برنامه شما می‌تواند از آن نشانه برای تأیید درخواست‌های API از طرف یک حساب کاربری یا حساب سرویس خاص استفاده کند. یک شیء سرویس برای API که می خواهید فراخوانی کنید بسازید. برای مثال، کد زیر از Google Drive API برای فهرست کردن نام فایل‌ها در Drive کاربر استفاده می‌کند.

const { google } = require('googleapis');

// Example of using Google Drive API to list filenames in user's Drive.
const drive = google.drive('v3');
drive.files.list({
  auth: oauth2Client,
  pageSize: 10,
  fields: 'nextPageToken, files(id, name)',
}, (err1, res1) => {
  if (err1) return console.log('The API returned an error: ' + err1);
  const files = res1.data.files;
  if (files.length) {
    console.log('Files:');
    files.map((file) => {
      console.log(`${file.name} (${file.id})`);
    });
  } else {
    console.log('No files found.');
  }
});

HTTP/REST

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

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

می‌توانید همه APIهای Google را امتحان کنید و دامنه آنها را در OAuth 2.0 Playground مشاهده کنید.

نمونه های HTTP GET

تماس با نقطه پایانی reports.query (API YouTube Analytics) با استفاده از هدر HTTP Authorization: Bearer ممکن است به شکل زیر باشد. توجه داشته باشید که باید رمز دسترسی خود را مشخص کنید:

GET /youtube/analytics/v1/reports?ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

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

GET https://www.googleapis.com/youtube/analytics/v1/reports?access_token=access_token&ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views

نمونه های curl

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

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/analytics/v1/reports?ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views

یا، گزینه پارامتر query string:

curl https://www.googleapis.com/youtube/analytics/v1/reports?access_token=access_token&ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views

مثال کامل

مثال زیر یک شی با فرمت JSON را چاپ می‌کند که داده‌های بازدیدها را برای کانال یوتیوب کاربر احراز هویت شده نشان می‌دهد پس از اینکه کاربر به برنامه اجازه بازیابی گزارش‌های YouTube Analytics را داد.

PHP

برای اجرای این مثال:

  1. در API Console، URL ماشین محلی را به لیست URL های تغییر مسیر اضافه کنید. به عنوان مثال، http://localhost:8080 را اضافه کنید.
  2. یک دایرکتوری جدید ایجاد کنید و به آن تغییر دهید. به عنوان مثال:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. با استفاده از Composer، Google API Client Library را برای PHP نصب کنید:
    composer require google/apiclient:^2.15.0
  4. فایل های index.php و oauth2callback.php را با محتوای زیر ایجاد کنید.
  5. مثال را با وب سرور آزمایشی داخلی PHP اجرا کنید:
    php -S localhost:8080 ~/php-oauth2-example

index.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');

// User granted permission as an access token is in the session.
if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
{
  $client->setAccessToken($_SESSION['access_token']);
  
  // Check if user granted Drive permission
  if ($_SESSION['granted_scopes_dict']['Drive']) {
    echo "Drive feature is enabled.";
    echo "</br>";
    $drive = new Drive($client);
    $files = array();
    $response = $drive->files->listFiles(array());
    foreach ($response->files as $file) {
        echo "File: " . $file->name . " (" . $file->id . ")";
        echo "</br>";
    }
  } else {
    echo "Drive feature is NOT enabled.";
    echo "</br>";
  }

   // Check if user granted Calendar permission
  if ($_SESSION['granted_scopes_dict']['Calendar']) {
    echo "Calendar feature is enabled.";
    echo "</br>";
  } else {
    echo "Calendar feature is NOT enabled.";
    echo "</br>";
  }
}
else
{
  // Redirect users to outh2call.php which redirects users to Google OAuth 2.0
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>

oauth2callback.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();

// Required, call the setAuthConfig function to load authorization credentials from
// client_secret.json file.
$client->setAuthConfigFile('client_secret.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF']);

// Required, to set the scope value, call the addScope function.
$client->addScope(Google_Service_YouTubeAnalytics::YT_ANALYTICS_READONLY);

// Enable incremental authorization. Recommended as a best practice.
$client->setIncludeGrantedScopes(true);

// Recommended, offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType("offline");

// Generate a URL for authorization as it doesn't contain code and error
if (!isset($_GET['code']) && !isset($_GET['error']))
{
  // Generate and set state value
  $state = bin2hex(random_bytes(16));
  $client->setState($state);
  $_SESSION['state'] = $state;

  // Generate a url that asks permissions.
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
}

// User authorized the request and authorization code is returned to exchange access and
// refresh tokens.
if (isset($_GET['code']))
{
  // Check the state value
  if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) {
    die('State mismatch. Possible CSRF attack.');
  }

  // Get access and refresh tokens (if access_type is offline)
  $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);

  /** Save access and refresh token to the session variables.
    * ACTION ITEM: In a production app, you likely want to save the
    *              refresh token in a secure persistent storage instead. */
  $_SESSION['access_token'] = $token;
  $_SESSION['refresh_token'] = $client->getRefreshToken();
  
  // Space-separated string of granted scopes if it exists, otherwise null.
  $granted_scopes = $client->getOAuth2Service()->getGrantedScope();

  // Determine which scopes user granted and build a dictionary
  $granted_scopes_dict = [
    'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
    'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
  ];
  $_SESSION['granted_scopes_dict'] = $granted_scopes_dict;
  
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

// An error response e.g. error=access_denied
if (isset($_GET['error']))
{
  echo "Error: ". $_GET['error'];
}
?>

پایتون

این مثال از چارچوب Flask استفاده می کند. این یک برنامه وب در http://localhost:8080 اجرا می کند که به شما امکان می دهد جریان OAuth 2.0 را آزمایش کنید. اگر به آن URL بروید، باید پنج پیوند را ببینید:

  • Call Drive API: این پیوند به صفحه‌ای اشاره می‌کند که در صورت اعطای مجوز توسط کاربران، سعی می‌کند یک درخواست API نمونه را اجرا کند. در صورت لزوم، جریان مجوز را شروع می کند. در صورت موفقیت آمیز بودن، صفحه پاسخ API را نمایش می دهد.
  • صفحه ساختگی برای فراخوانی Calendar API: این پیوند به صفحه maock اشاره می کند که در صورت اعطای مجوز به کاربران سعی می کند نمونه درخواست API تقویم را اجرا کند. در صورت لزوم، جریان مجوز را شروع می کند. در صورت موفقیت آمیز بودن، صفحه پاسخ API را نمایش می دهد.
  • جریان تأیید را مستقیماً آزمایش کنید: این پیوند به صفحه ای اشاره می کند که سعی می کند کاربر را از طریق جریان مجوز ارسال کند. برنامه برای ارسال درخواست های مجاز API از طرف کاربر مجوز درخواست می کند.
  • Revoke current credentials: این پیوند به صفحه ای اشاره می کند که مجوزهایی را که کاربر قبلاً به برنامه اعطا کرده است لغو می کند .
  • Clear Flask Session Credentials: این پیوند اعتبارنامه های مجوز ذخیره شده در جلسه Flask را پاک می کند. این به شما امکان می‌دهد ببینید چه اتفاقی می‌افتد اگر کاربری که قبلاً به برنامه شما اجازه داده است بخواهد یک درخواست API را در یک جلسه جدید اجرا کند. همچنین به شما امکان می‌دهد پاسخ API را مشاهده کنید که اگر کاربر مجوزهای اعطا شده به برنامه شما را لغو کرده باشد، و برنامه شما همچنان سعی کند درخواستی را با یک نشانه دسترسی لغو شده تأیید کند.
# -*- coding: utf-8 -*-

import os
import flask
import requests

import google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery

# This variable specifies the name of a file that contains the OAuth 2.0
# information for this application, including its client_id and client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"

# The OAuth 2.0 access scope allows for access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/yt-analytics.readonly',
          'https://www.googleapis.com/auth/calendar.readonly']
API_SERVICE_NAME = 'youtubeAnalytics'
API_VERSION = 'v1'

app = flask.Flask(__name__)
# Note: A secret key is included in the sample so that it works.
# If you use this code in your application, replace this with a truly secret
# key. See https://flask.palletsprojects.com/quickstart/#sessions.
app.secret_key = 'REPLACE ME - this value is here as a placeholder.'

@app.route('/')
def index():
  return print_index_table()

@app.route('/drive')
def drive_api_request():
  if 'credentials' not in flask.session:
    return flask.redirect('authorize')

  features = flask.session['features']

  if features['drive']:
    # Load credentials from the session.
    credentials = google.oauth2.credentials.Credentials(
        **flask.session['credentials'])

    youtube = googleapiclient.discovery.build(
        API_SERVICE_NAME, API_VERSION, credentials=credentials)

    report = youtube.reports().query(ids='channel==MINE', start_date='2016-05-01', end_date='2016-06-30', metrics='views').execute()

    # Save credentials back to session in case access token was refreshed.
    # ACTION ITEM: In a production app, you likely want to save these
    #              credentials in a persistent database instead.
    flask.session['credentials'] = credentials_to_dict(credentials)

    return flask.jsonify(**report)
  else:
    # User didn't authorize read-only Drive activity permission.
    # Update UX and application accordingly
    return '<p>Drive feature is not enabled.</p>'

@app.route('/calendar')
    def calendar_api_request():
      if 'credentials' not in flask.session:
        return flask.redirect('authorize')

      features = flask.session['features']

      if features['calendar']:
        # User authorized Calendar read permission.
        # Calling the APIs, etc.
        return ('<p>User granted the Google Calendar read permission. '+
                'This sample code does not include code to call Calendar</p>')
      else:
        # User didn't authorize Calendar read permission.
        # Update UX and application accordingly
        return '<p>Calendar feature is not enabled.</p>'

@app.route('/authorize')
def authorize():
  # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES)

  # The URI created here must exactly match one of the authorized redirect URIs
  # for the OAuth 2.0 client, which you configured in the API Console. If this
  # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
  # error.
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  authorization_url, state = flow.authorization_url(
      # Enable offline access so that you can refresh an access token without
      # re-prompting the user for permission. Recommended for web server apps.
      access_type='offline',
      # Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes='true')

  # Store the state so the callback can verify the auth server response.
  flask.session['state'] = state

  return flask.redirect(authorization_url)

@app.route('/oauth2callback')
def oauth2callback():
  # Specify the state when creating the flow in the callback so that it can
  # verified in the authorization server response.
  state = flask.session['state']

  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  # Use the authorization server's response to fetch the OAuth 2.0 tokens.
  authorization_response = flask.request.url
  flow.fetch_token(authorization_response=authorization_response)

  # Store credentials in the session.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  credentials = flow.credentials
  
  credentials = credentials_to_dict(credentials)
  flask.session['credentials'] = credentials

  # Check which scopes user granted
  features = check_granted_scopes(credentials)
  flask.session['features'] = features
  return flask.redirect('/')
  

@app.route('/revoke')
def revoke():
  if 'credentials' not in flask.session:
    return ('You need to <a href="/authorize">authorize</a> before ' +
            'testing the code to revoke credentials.')

  credentials = google.oauth2.credentials.Credentials(
    **flask.session['credentials'])

  revoke = requests.post('https://oauth2.googleapis.com/revoke',
      params={'token': credentials.token},
      headers = {'content-type': 'application/x-www-form-urlencoded'})

  status_code = getattr(revoke, 'status_code')
  if status_code == 200:
    return('Credentials successfully revoked.' + print_index_table())
  else:
    return('An error occurred.' + print_index_table())

@app.route('/clear')
def clear_credentials():
  if 'credentials' in flask.session:
    del flask.session['credentials']
  return ('Credentials have been cleared.<br><br>' +
          print_index_table())

def credentials_to_dict(credentials):
  return {'token': credentials.token,
          'refresh_token': credentials.refresh_token,
          'token_uri': credentials.token_uri,
          'client_id': credentials.client_id,
          'client_secret': credentials.client_secret,
          'granted_scopes': credentials.granted_scopes}

def check_granted_scopes(credentials):
  features = {}
  if 'https://www.googleapis.com/auth/yt-analytics.readonly' in credentials['granted_scopes']:
    features['drive'] = True
  else:
    features['drive'] = False

  if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']:
    features['calendar'] = True
  else:
    features['calendar'] = False

  return features

def print_index_table():
  return ('<table>' +
          '<tr><td><a href="/test">Test an API request</a></td>' +
          '<td>Submit an API request and see a formatted JSON response. ' +
          '    Go through the authorization flow if there are no stored ' +
          '    credentials for the user.</td></tr>' +
          '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
          '<td>Go directly to the authorization flow. If there are stored ' +
          '    credentials, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' +
          '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
          '<td>Revoke the access token associated with the current user ' +
          '    session. After revoking credentials, if you go to the test ' +
          '    page, you should see an <code>invalid_grant</code> error.' +
          '</td></tr>' +
          '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
          '<td>Clear the access token currently stored in the user session. ' +
          '    After clearing the token, if you <a href="/test">test the ' +
          '    API request</a> again, you should go back to the auth flow.' +
          '</td></tr></table>')

if __name__ == '__main__':
  # When running locally, disable OAuthlib's HTTPs verification.
  # ACTION ITEM for developers:
  #     When running in production *do not* leave this option enabled.
  os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

  # This disables the requested scopes and granted scopes check.
  # If users only grant partial request, the warning would not be thrown.
  os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'

  # Specify a hostname and port that are set as a valid redirect URI
  # for your API project in the Google API Console.
  app.run('localhost', 8080, debug=True)

روبی

این مثال از چارچوب سیناترا استفاده می کند.

require 'googleauth'
require 'googleauth/web_user_authorizer'
require 'googleauth/stores/redis_token_store'

require 'google/apis/youtube_analytics_v1'
require 'google/apis/calendar_v3'

require 'sinatra'

configure do
  enable :sessions

  # Required, call the from_file method to retrieve the client ID from a
  # client_secret.json file.
  set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')

  # Required, scope value
  # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
  scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
           'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']

  # Required, Authorizers require a storage instance to manage long term persistence of
  # access and refresh tokens.
  set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)

  # Required, indicate where the API server will redirect the user after the user completes
  # the authorization flow. The redirect URI is required. The value must exactly
  # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
  # configured in the API Console. If this value doesn't match an authorized URI,
  # you will get a 'redirect_uri_mismatch' error.
  set :callback_uri, '/oauth2callback'

  # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
  # from the client_secret.json file. To get these credentials for your application, visit
  # https://console.cloud.google.com/apis/credentials.
  set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope,
                          settings.token_store, callback_uri: settings.callback_uri)
end

get '/' do
  # NOTE: Assumes the user is already authenticated to the app
  user_id = request.session['user_id']

  # Fetch stored credentials for the user from the given request session.
  # nil if none present
  credentials = settings.authorizer.get_credentials(user_id, request)

  if credentials.nil?
    # Generate a url that asks the user to authorize requested scope(s).
    # Then, redirect user to the url.
    redirect settings.authorizer.get_authorization_url(request: request)
  end
  
  # User authorized the request. Now, check which scopes were granted.
  if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)
    # User authorized read-only Drive activity permission.
    # Example of using Google Drive API to list filenames in user's Drive.
    youtube = Google::Apis::YoutubeAnalyticsV1::YouTubeAnalyticsService.new
    report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views', options: { authorization: auth_client })
    
    "<pre>#{JSON.pretty_generate(report.to_h)}</pre>"
  else
    # User didn't authorize read-only Drive activity permission.
    # Update UX and application accordingly
  end

  # Check if user authorized Calendar read permission.
  if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)
    # User authorized Calendar read permission.
    # Calling the APIs, etc.
  else
    # User didn't authorize Calendar read permission.
    # Update UX and application accordingly
  end
end

# Receive the callback from Google's OAuth 2.0 server.
get '/oauth2callback' do
  # Handle the result of the oauth callback. Defers the exchange of the code by
  # temporarily stashing the results in the user's session.
  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url
end

Node.js

برای اجرای این مثال:

  1. در API Console، URL ماشین محلی را به لیست URL های تغییر مسیر اضافه کنید. به عنوان مثال، http://localhost را اضافه کنید.
  2. مطمئن شوید که LTS تعمیر و نگهداری، LTS فعال یا نسخه فعلی Node.js را نصب کرده اید.
  3. یک دایرکتوری جدید ایجاد کنید و به آن تغییر دهید. به عنوان مثال:
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. Google API Client Library را برای Node.js با استفاده از npm نصب کنید:
    npm install googleapis
  5. فایل main.js را با محتوای زیر ایجاد کنید.
  6. مثال را اجرا کنید:
    node .\main.js

main.js

const http = require('http');
const https = require('https');
const url = require('url');
const { google } = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
 * To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
const scopes = [
  'https://www.googleapis.com/auth/yt-analytics.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

/* Global variable that stores user credential in this code example.
 * ACTION ITEM for developers:
 *   Store user's refresh token in your data store if
 *   incorporating this code into your real app.
 *   For more information on handling refresh tokens,
 *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
 */
let userCredential = null;

async function main() {
  const app = express();

  app.use(session({
    secret: 'your_secure_secret_key', // Replace with a strong secret
    resave: false,
    saveUninitialized: false,
  }));

  // Example on redirecting user to Google's OAuth 2.0 server.
  app.get('/', async (req, res) => {
    // Generate a secure random state value.
    const state = crypto.randomBytes(32).toString('hex');
    // Store state in the session
    req.session.state = state;

    // Generate a url that asks permissions for the Drive activity and Google Calendar scope
    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true,
      // Include the state parameter to reduce the risk of CSRF attacks.
      state: state
    });

    res.redirect(authorizationUrl);
  });

  // Receive the callback from Google's OAuth 2.0 server.
  app.get('/oauth2callback', async (req, res) => {
    // Handle the OAuth 2.0 server response
    let q = url.parse(req.url, true).query;

    if (q.error) { // An error response e.g. error=access_denied
      console.log('Error:' + q.error);
    } else if (q.state !== req.session.state) { //check state value
      console.log('State mismatch. Possible CSRF attack');
      res.end('State mismatch. Possible CSRF attack');
    } else { // Get access and refresh tokens (if access_type is offline)
      let { tokens } = await oauth2Client.getToken(q.code);
      oauth2Client.setCredentials(tokens);

      /** Save credential to the global variable in case access token was refreshed.
        * ACTION ITEM: In a production app, you likely want to save the refresh token
        *              in a secure persistent database instead. */
      userCredential = tokens;
      
      // User authorized the request. Now, check which scopes were granted.
      if (tokens.scope.includes('https://www.googleapis.com/auth/yt-analytics.readonly'))
      {
        // User authorized read-only Drive activity permission.
        // Example of using Google Drive API to list filenames in user's Drive.
        const drive = google.drive('v3');
        drive.files.list({
          auth: oauth2Client,
          pageSize: 10,
          fields: 'nextPageToken, files(id, name)',
        }, (err1, res1) => {
          if (err1) return console.log('The API returned an error: ' + err1);
          const files = res1.data.files;
          if (files.length) {
            console.log('Files:');
            files.map((file) => {
              console.log(`${file.name} (${file.id})`);
            });
          } else {
            console.log('No files found.');
          }
        });
      }
      else
      {
        // User didn't authorize read-only Drive activity permission.
        // Update UX and application accordingly
      }

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

  // Example on revoking a token
  app.get('/revoke', async (req, res) => {
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;

    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };

    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });

    postReq.on('error', error => {
      console.log(error)
    });

    // Post the request with data
    postReq.write(postData);
    postReq.end();
  });


  const server = http.createServer(app);
  server.listen(8080);
}
main().catch(console.error);

HTTP/REST

این مثال پایتون از چارچوب Flask و کتابخانه Requests برای نشان دادن جریان وب OAuth 2.0 استفاده می کند. توصیه می کنیم از Google API Client Library برای پایتون برای این جریان استفاده کنید. (مثال موجود در تب Python از کتابخانه مشتری استفاده می کند.)

import json
import flask
import requests

app = flask.Flask(__name__)

# To get these credentials (CLIENT_ID CLIENT_SECRET) and for your application, visit
# https://console.cloud.google.com/apis/credentials.
CLIENT_ID = '123456789.apps.googleusercontent.com'
CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app

# Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
SCOPE = 'https://www.googleapis.com/auth/yt-analytics.readonly https://www.googleapis.com/auth/calendar.readonly'

# Indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
REDIRECT_URI = 'http://example.com/oauth2callback'

@app.route('/')
def index():
  if 'credentials' not in flask.session:
    return flask.redirect(flask.url_for('oauth2callback'))

  credentials = json.loads(flask.session['credentials'])

  if credentials['expires_in'] <= 0:
    return flask.redirect(flask.url_for('oauth2callback'))
  else: 
    # User authorized the request. Now, check which scopes were granted.
    if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['scope']:
      # User authorized read-only Drive activity permission.
      # Example of using Google Drive API to list filenames in user's Drive.
      headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
      req_uri = 'https://www.googleapis.com/youtube/analytics/v1/reports'
      r = requests.get(req_uri, headers=headers).text
    else:
      # User didn't authorize read-only Drive activity permission.
      # Update UX and application accordingly
      r = 'User did not authorize Drive permission.'

    # Check if user authorized Calendar read permission.
    if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['scope']:
      # User authorized Calendar read permission.
      # Calling the APIs, etc.
      r += 'User authorized Calendar permission.'
    else:
      # User didn't authorize Calendar read permission.
      # Update UX and application accordingly
      r += 'User did not authorize Calendar permission.'

  return r

@app.route('/oauth2callback')
def oauth2callback():
  if 'code' not in flask.request.args:
    state = str(uuid.uuid4())
    flask.session['state'] = state
    # Generate a url that asks permissions for the Drive activity
    # and Google Calendar scope. Then, redirect user to the url.
    auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI,
                                                                          SCOPE, state)
    return flask.redirect(auth_uri)
  else:
    if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']:
      return 'State mismatch. Possible CSRF attack.', 400

    auth_code = flask.request.args.get('code')
    data = {'code': auth_code,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI,
            'grant_type': 'authorization_code'}

    # Exchange authorization code for access and refresh tokens (if access_type is offline)
    r = requests.post('https://oauth2.googleapis.com/token', data=data)
    flask.session['credentials'] = r.text
    return flask.redirect(flask.url_for('index'))

if __name__ == '__main__':
  import uuid
  app.secret_key = str(uuid.uuid4())
  app.debug = False
  app.run()

قوانین اعتبارسنجی URI را تغییر مسیر دهید

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

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

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

میزبان

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

دامنه
  • میزبان TLD ( دامنه های سطح بالا ) باید به لیست پسوند عمومی تعلق داشته باشد.
  • دامنه میزبان نمی تواند “googleusercontent.com” باشد.
  • URI‌های تغییر مسیر نمی‌توانند شامل دامنه‌های کوتاه‌کننده URL (مثلا goo.gl ) باشند، مگر اینکه برنامه مالک دامنه باشد. علاوه بر این، اگر برنامه‌ای که دارای دامنه کوتاه‌کننده است، تغییر مسیر به آن دامنه را انتخاب کند، آن URI تغییر مسیر یا باید حاوی “/google-callback/” در مسیر خود باشد یا به “/google-callback” ختم شود.
  • اطلاعات کاربری

    URI های تغییر مسیر نمی توانند شامل زیرمجموعه اطلاعات کاربر باشند.

    مسیر

    URI های تغییر مسیر نمی توانند شامل پیمایش مسیر (همچنین به نام بک ترک دایرکتوری) باشند که با “/..” یا “\..” یا رمزگذاری URL آنها نشان داده می شود.

    پرس و جو

    URI های تغییر مسیر نمی توانند حاوی تغییر مسیرهای باز باشند.

    قطعه

    URI های تغییر مسیر نمی توانند شامل جزء قطعه باشند.

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

    مجوز افزایشی

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

    به عنوان مثال، فرض کنید برنامه‌ای گزارش‌های YouTube Analytics را بازیابی می‌کند، برخی از آنها گزارش‌های پولی هستند که نیاز به دسترسی به دامنه اضافی دارند که برای گزارش‌های دیگر مورد نیاز نیست. در این مورد، در زمان ورود به سیستم، برنامه فقط ممکن است درخواست دسترسی به حوزه https://www.googleapis.com/auth/yt-analytics.readonly کند. با این حال، اگر کاربر سعی در بازیابی گزارش پولی داشته باشد، برنامه همچنین می‌تواند درخواست دسترسی به حوزه https://www.googleapis.com/auth/yt-analytics-monetary.readonly نیز بکند.

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

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

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

    نمونه کدهای خاص زبان در مرحله 1: تنظیم پارامترهای مجوز و نمونه URL تغییر مسیر HTTP/REST در مرحله 2: هدایت مجدد به سرور OAuth 2.0 Google همگی از مجوز افزایشی استفاده می کنند. نمونه‌های کد زیر نیز کدی را نشان می‌دهند که برای استفاده از مجوز افزایشی باید اضافه کنید.

    PHP

    $client->setIncludeGrantedScopes(true);

    پایتون

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

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    روبی

    auth_client.update!(
      :additional_parameters => {"include_granted_scopes" => "true"}
    )

    Node.js

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });

    HTTP/REST

    در این مثال، برنامه فراخوان درخواست دسترسی برای بازیابی داده های YouTube Analytics کاربر را علاوه بر هر گونه دسترسی دیگری که کاربر قبلاً به برنامه داده است، می کند.

    GET https://accounts.google.com/o/oauth2/v2/auth?
      scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly&
      access_type=offline&
      state=security_token%3D138rk%3Btarget_url%3Dhttp...index&
      redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
      response_type=code&
      client_id=client_id&
      include_granted_scopes=true
    
          

    Refreshing an access token (offline access)

    Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.

    • If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
    • If you are not using a client library, you need to set the access_type HTTP query parameter to offline when redirecting the user to Google's OAuth 2.0 server. In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.

    Requesting offline access is a requirement for any application that needs to access a Google API when the user is not present. For example, an app that performs backup services or executes actions at predetermined times needs to be able to refresh its access token when the user is not present. The default style of access is called online.

    Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.

    PHP

    If your application needs offline access to a Google API, set the API client's access type to offline:

    $client->setAccessType("offline");

    پس از اعطای دسترسی آفلاین به دامنه های درخواستی توسط کاربر، زمانی که کاربر آفلاین است، می توانید به استفاده از سرویس گیرنده API برای دسترسی به API های Google از طرف او ادامه دهید. شی کلاینت در صورت نیاز، نشانه دسترسی را بازخوانی می کند.

    پایتون

    در پایتون، آرگومان کلمه کلیدی access_type را روی offline قرار دهید تا مطمئن شوید که می‌توانید رمز دسترسی را بدون درخواست مجدد از کاربر برای مجوز، تازه‌سازی کنید. بسیار ممکن است که access_type تنها آرگومان کلیدواژه ای نباشد که تنظیم می کنید، همانطور که در مثال زیر نشان داده شده است.

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    پس از اعطای دسترسی آفلاین به دامنه های درخواستی توسط کاربر، زمانی که کاربر آفلاین است، می توانید به استفاده از سرویس گیرنده API برای دسترسی به API های Google از طرف او ادامه دهید. شی کلاینت در صورت نیاز، نشانه دسترسی را بازخوانی می کند.

    روبی

    اگر برنامه شما نیاز به دسترسی آفلاین به Google API دارد، نوع دسترسی مشتری API را روی offline تنظیم کنید:

    auth_client.update!(
      :additional_parameters => {"access_type" => "offline"}
    )

    پس از اعطای دسترسی آفلاین به دامنه های درخواستی توسط کاربر، زمانی که کاربر آفلاین است، می توانید به استفاده از سرویس گیرنده API برای دسترسی به API های Google از طرف او ادامه دهید. شی کلاینت در صورت نیاز، نشانه دسترسی را بازخوانی می کند.

    Node.js

    اگر برنامه شما نیاز به دسترسی آفلاین به Google API دارد، نوع دسترسی مشتری API را روی offline تنظیم کنید:

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });

    پس از اعطای دسترسی آفلاین به دامنه های درخواستی توسط کاربر، زمانی که کاربر آفلاین است، می توانید به استفاده از سرویس گیرنده API برای دسترسی به API های Google از طرف او ادامه دهید. شی کلاینت در صورت نیاز، نشانه دسترسی را بازخوانی می کند.

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

    oauth2Client.on('tokens', (tokens) => {
      if (tokens.refresh_token) {
        // store the refresh_token in your secure persistent database
        console.log(tokens.refresh_token);
      }
      console.log(tokens.access_token);
    });

    این رویداد نشانه‌ها فقط در اولین مجوز رخ می‌دهد، و باید هنگام فراخوانی متد generateAuthUrl ، access_type خود را روی offline تنظیم کنید تا رمز تازه‌سازی را دریافت کنید. اگر قبلاً مجوزهای لازم را بدون تنظیم محدودیت‌های مناسب برای دریافت نشانه‌ی تازه‌سازی به برنامه‌تان داده‌اید، باید برنامه را مجدداً برای دریافت نشانه‌ی تازه‌سازی تأیید کنید.

    برای تنظیم refresh_token در زمان دیگری، می توانید از روش setCredentials استفاده کنید:

    oauth2Client.setCredentials({
      refresh_token: `STORED_REFRESH_TOKEN`
    });

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

    HTTP/REST

    برای تازه کردن یک نشانه دسترسی، برنامه شما یک درخواست HTTPS POST به سرور مجوز Google ( https://oauth2.googleapis.com/token ) ارسال می کند که شامل پارامترهای زیر است:

    فیلدها
    client_id شناسه مشتری به دست آمده از API Console.
    client_secret راز مشتری به دست آمده از API Console.
    grant_type همانطور که در مشخصات OAuth 2.0 تعریف شده است ، مقدار این فیلد باید روی refresh_token تنظیم شود.
    refresh_token رمز به‌روزرسانی از تبادل کد مجوز بازگشت.

    قطعه زیر یک نمونه درخواست را نشان می دهد:

    POST /token HTTP/1.1
    Host: oauth2.googleapis.com
    Content-Type: application/x-www-form-urlencoded
    
    client_id=your_client_id&
    client_secret=your_client_secret&
    refresh_token=refresh_token&
    grant_type=refresh_token

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

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

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

    باطل کردن یک نشانه

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

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

    PHP

    برای لغو برنامه‌ای یک نشانه، revokeToken() را فراخوانی کنید:

    $client->revokeToken();

    پایتون

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

    requests.post('https://oauth2.googleapis.com/revoke',
        params={'token': credentials.token},
        headers = {'content-type': 'application/x-www-form-urlencoded'})

    روبی

    برای لغو برنامه‌ای یک نشانه، یک درخواست HTTP به نقطه پایانی oauth2.revoke ارسال کنید:

    uri = URI('https://oauth2.googleapis.com/revoke')
    response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)

    توکن می تواند یک نشانه دسترسی یا یک نشانه تازه سازی باشد. اگر توکن یک نشانه دسترسی باشد و دارای یک نشانه رفرش متناظر باشد، توکن رفرش نیز باطل می شود.

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

    Node.js

    برای لغو برنامه‌ای یک نشانه، یک درخواست HTTPS POST برای /revoke endpoint ارسال کنید:

    const https = require('https');
    
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;
    
    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };
    
    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });
    
    postReq.on('error', error => {
      console.log(error)
    });
    
    // Post the request with data
    postReq.write(postData);
    postReq.end();

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

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

    HTTP/REST

    برای لغو برنامه‌ای یک نشانه، برنامه شما درخواستی به 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 به همراه یک کد خطا برگردانده می شود.

    اجرای حفاظت از حساب های متقابل

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

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

    • 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

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