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

این سند توضیح می‌دهد که برنامه‌های کارساز وب چگونه از «کتابخانه‌های کارخواه Google API» یا نقطه‌های پایانی Google OAuth 2.0 برای پیاده‌سازی مجوز OAuth 2.0 جهت دسترسی به YouTube Data API استفاده می‌کنند.

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

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

برنامه‌های کارساز وب اغلب از حساب‌های سرویس نیز برای مجاز کردن درخواست‌های API استفاده می‌کنند، به‌ویژه هنگام فراخوانی Cloud APIs برای دسترسی به داده‌های مبتنی بر پروژه به‌جای داده‌های مختص کاربر. برنامه‌های کارساز وب می‌توانند از حساب‌های خدمات همراه با مجوز کاربر استفاده کنند. توجه داشته باشید که YouTube Data API از جریان حساب سرویس فقط برای مالکان محتوای YouTube که مالک و مدیر چندین کانال YouTube هستند پشتیبانی می‌کند. به‌طور مشخص، مالکان محتوا می‌توانند از حساب‌های سرویس برای فراخوانی روش‌های API که از پارامتر درخواست onBehalfOfContentOwner پشتیبانی می‌کنند استفاده کنند.

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

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

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

«کتابخانه‌های مشتری Google API» برای برنامه‌های سمت سرور به زبان‌های زیر دردسترس است:

پیش‌نیازها

فعال کردن میاناهای برنامه‌سازی کاربردی برای پروژه

هر برنامه‌ای که میاناهای برنامه‌سازی کاربردی Google را فراخوانی می‌کند باید آن میاناهای برنامه‌سازی کاربردی را در «کنسول میانای برنامه‌سازی کاربردی» فعال کند.

برای فعال کردن میانای برنامه‌سازی کاربردی برای پروژه:

  1. کتابخانه میانای برنامه‌سازی کاربردی را در «کنسول Google API» باز کنید.
  2. اگر درخواست شد، پروژه‌ای را انتخاب کنید یا پروژه جدیدی ایجاد کنید.
  3. از صفحه کتابخانه برای پیدا کردن و فعال کردن YouTube Data API استفاده کنید. هر API دیگری را که برنامه‌تان استفاده خواهد کرد پیدا کنید و آن‌ها را نیز فعال کنید.

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

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

  1. به صفحه کارخواهان بروید.
  2. روی ایجاد کارخواه کلیک کنید.
  3. نوع برنامه برنامه وب را انتخاب کنید.
  4. فرم را تکمیل کنید و روی ایجاد کلیک کنید. برنامه‌هایی که از زبان‌ها و چارچوب‌هایی مثل PHP،‏ Java،‏ Python،‏ Ruby، و .NET استفاده می‌کنند باید شناسه‌های منبع یکنواخت بازهدایت مجاز را مشخص کنند. URIهای هدایت نقاط پایانی هستند که سرور OAuth 2.0 می‌تواند پاسخ‌ها را به آن‌ها ارسال کند. این نقاط پایانی باید از قوانین اعتبارسنجی Google پیروی کنند.

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

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

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

شناسایی کردن دامنه‌های دسترسی

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

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

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

YouTube Data API v3 از دامنه‌های زیر استفاده می‌کند:

دامنه توضیحات
https://www. googleapis. com/ auth/ youtube حساب YouTube خود را مدیریت کنید
https://www. googleapis. com/ auth/ youtube. channel-memberships. creator فهرستی از اعضای فعال فعلی کانال خود، سطح فعلی آنها و زمان عضویت آنها را مشاهده کنید
https://www. googleapis. com/ auth/ youtube. force-ssl ویدیوها، رتبه‌بندی‌ها، نظرات و زیرنویس‌های YouTube خود را مشاهده، ویرایش و برای همیشه حذف کنید
https://www. googleapis. com/ auth/ youtube. readonly حساب YouTube خود را مشاهده کنید
https://www. googleapis. com/ auth/ youtube. upload ویدیوهای YouTube خود را مدیریت کنید
https://www. googleapis. com/ auth/ youtubepartner دارایی ها و محتوای مرتبط خود را در YouTube مشاهده و مدیریت کنید
https://www. googleapis. com/ auth/ youtubepartner-channel-audit اطلاعات خصوصی مربوط به کانال YouTube خود را در طول فرآیند ممیزی با شریک YouTube مشاهده کنید

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

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

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

PHP

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

  • ‫PHP نسخه ۸.۰ یا بالاتر با نصب میانای خط فرمان (CLI) و افزونه JSON.
  • ابزار مدیریت وابستگی Composer.
  • کتابخانه کارخواهان Google APIs برای PHP:

    composer require google/apiclient:^2.15.0

برای اطلاعات بیشتر، کتابخانه مشتری Google APIs برای PHP را ببینید.

Python

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

  • Python نسخه ۳.۷ یا بالاتر
  • ابزار مدیریت بسته pip.
  • نسخه ۲.۰ «کتابخانه کارخواه Google APIs» برای Python:
    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 را مرور کنید.

Ruby

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

  • ‫Ruby نسخه ۲.۶ یا بالاتر
  • کتابخانه Google Auth برای Ruby:

    gem install googleauth
  • چارچوب برنامه وب Sinatra Ruby.

    gem install sinatra

Node.js

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

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

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

مرحله ۱: تنظیم پارامترهای مجوز

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

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

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

PHP

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

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

برای مثال، این کد دسترسی آفلاین برای مدیریت حساب YouTube کاربر را درخواست می‌کند:

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_YOUTUBE::YOUTUBE_FORCE_SSL);

// 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);

Python

تکه کد زیر از واحد google-auth-oauthlib.flow برای ساختن درخواست مجوز استفاده می‌کند.

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

برای مثال، این کد برای مدیریت حساب YouTube کاربر، درخواست دسترسی آفلاین می‌کند:

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/youtube.force-ssl'])

# 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')

Ruby

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

برای مثال، این کد دسترسی آفلاین برای مدیریت حساب YouTube کاربر را درخواست می‌کند:

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

require 'google/apis/youtube_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 
scope = 'https://www.googleapis.com/auth/youtube.force-ssl'

# 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، مثل تولید نشانی‌های وب درخواست مجوز و اعمال کدهای دسترسی در درخواست‌های HTTP استفاده می‌کند.

Node.js

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

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

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 YouTube API
const scopes = [
  'https://www.googleapis.com/auth/youtube.force-ssl'
];

// 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

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

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

پارامترها
client_id الزامی

شناسه کارخواه برای برنامه شما. این مقدار را می‌توانید در «کنسول Cloud» صفحه «کارخواه‌ها» پیدا کنید.

redirect_uri الزامی

تعیین می‌کند که سرور میانای برنامه‌سازی کاربردی پس‌از تکمیل جریان مجوز توسط کاربر، او را به کجا هدایت کند. این مقدار باید دقیقاً با یکی از URIهای هدایت مجاز برای کارخواه OAuth 2.0 که در صفحه «کارخواه‌ها» در Cloud Console کارخواه پیکربندی کرده‌اید مطابقت داشته باشد. اگر این مقدار با نشانی وب بازگردان مجاز برای client_id ارائه‌شده مطابقت نداشته باشد، خطای redirect_uri_mismatch دریافت خواهید کرد.

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

response_type الزامی

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

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

scope الزامی

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

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

YouTube Data API v3 از دامنه‌های زیر استفاده می‌کند:

دامنه توضیحات
https://www. googleapis. com/ auth/ youtube حساب YouTube خود را مدیریت کنید
https://www. googleapis. com/ auth/ youtube. channel-memberships. creator فهرستی از اعضای فعال فعلی کانال خود، سطح فعلی آنها و زمان عضویت آنها را مشاهده کنید
https://www. googleapis. com/ auth/ youtube. force-ssl ویدیوها، رتبه‌بندی‌ها، نظرات و زیرنویس‌های YouTube خود را مشاهده، ویرایش و برای همیشه حذف کنید
https://www. googleapis. com/ auth/ youtube. readonly حساب YouTube خود را مشاهده کنید
https://www. googleapis. com/ auth/ youtube. upload ویدیوهای YouTube خود را مدیریت کنید
https://www. googleapis. com/ auth/ youtubepartner دارایی ها و محتوای مرتبط خود را در YouTube مشاهده و مدیریت کنید
https://www. googleapis. com/ auth/ youtubepartner-channel-audit اطلاعات خصوصی مربوط به کانال YouTube خود را در طول فرآیند ممیزی با شریک YouTube مشاهده کنید

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

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

access_type توصیه‌شده

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

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

state توصیه‌شده

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

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

include_granted_scopes اختیاری

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

login_hint اختیاری

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

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

prompt اختیاری

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

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

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

مرحله ۲: هدایت کردن به سرور OAuth 2.0 در Google

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

PHP

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

Python

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

return flask.redirect(authorization_url)

Ruby

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

Node.js

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

HTTP/REST

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

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

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.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 متعلق به Google کاربر را اصالت‌سنجی می‌کند و موافقت کاربر را برای دسترسی برنامه شما به دامنه‌های درخواستی دریافت می‌کند. پاسخ بااستفاده از نشانی وب هدایت مجددی که مشخص کرده‌اید به برنامه‌تان ارسال می‌شود.

مرحله ۳: Google از کاربر درخواست رضایت می‌کند

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

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

خطاها

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

admin_policy_enforced

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

disallowed_useragent

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

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

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

org_internal

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

invalid_client

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

deleted_client

کارخواه OAuth که برای درخواست استفاده می‌شود حذف شده است. حذف می‌تواند به‌صورت دستی یا به‌طور خودکار در مورد کاربران استفاده‌نشده انجام شود. مشتریان حذف‌شده را می‌توان ظرف ۳۰ روز پس‌از حذف بازیابی کرد. بیشتر بدانید .

invalid_grant

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

redirect_uri_mismatch

redirect_uri ارسال‌شده در درخواست مجوز با نشانی وب هدایت مجاز برای شناسه کارخواه OAuth مطابقت ندارد. URIهای هدایت مجاز را در Google Cloud Console صفحه کارخواه‌ها مرور کنید.

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

invalid_request

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

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

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

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

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

پاسخ خطا:

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

پاسخ کد مجوز:

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

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

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

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.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، مرورگرتان شما را به OAuth 2.0 Playground هدایت می‌کند که ابزاری برای آزمایش جریان‌های OAuth است. خواهید دید که OAuth 2.0 Playground به‌طور خودکار کد مجوز را ضبط کرده است.

مرحله ۵: معاوضه کد مجوز با ژتون‌های بازآوری و دسترسی

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

PHP

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

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

Python

در صفحه برگشت تماس، از کتابخانه 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/youtube.force-ssl'],
    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 browser session storage, but for security: client_id, client_secret,
# and token_uri are instead stored only on the backend server.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'granted_scopes': credentials.granted_scopes}

Ruby

در صفحه برگشت تماس، از کتابخانه 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 را فراخوانی کنید و پارامترهای زیر را تنظیم کنید:

فیلدها
client_id شناسه کارخواه به‌دست‌آمده از صفحه کارخواه‌ها در «کنسول Cloud».
client_secret اختیاری

رمز کارخواه به‌دست‌آمده از صفحه کارخواه‌ها در «کنسول Cloud».

code کد مجوز برگشت‌داده‌شده از درخواست اولیه.
grant_type همان‌طور که در مشخصات OAuth 2.0 تعریف شده است، مقدار این فیلد باید روی authorization_code تنظیم شود.
redirect_uri یکی از نشانی‌های وب هدایت فهرست‌شده برای پروژه شما در Cloud Console صفحه «کارخواه‌ها» برای client_id داده‌شده.

اگرچه استفاده از DPoP اختیاری است، اما برای افزایش امنیت توصیه می‌شود. امنیت DPoP به محدود شدن کلید خصوصی به یک دستگاه واحد بستگی دارد؛ توصیه می‌کنیم آن را به‌گونه‌ای ذخیره کنید که نتوان آن را از دستگاه کپی کرد، برای مثال بااستفاده از TPM،‏ Secure Enclaves، یا سایر محل‌های ذخیره کلید با پشتیبانی سخت‌افزار. برای استفاده از DPoP، برنامه شما باید برای هر درخواست به نقطه پایانی توکن، یک JWT اثبات DPoP جدید و منحصربه‌فرد تولید کند و آن را به‌عنوان سرصفحه درخواست HTTP اضافه کند.

سرایند الزامی شرح
DPoP اختیاری اثبات DPoP یک JWT است که مالکیت کلید خصوصی را اثبات می‌کند. این سرصفحه است، نه پارامتر. درصورت ارائه، نشان‌های برگردانده‌شده به این کلید محدود می‌شوند. برای هر درخواست باید مدرک جدید و منحصربه‌فردی تولید شود و باید شامل ادعاهای htm (روش HTTP) و htu (نشانی وب HTTP) باشد که با درخواست مطابقت داشته باشد.

تکه زیر یک درخواست نمونه را نشان می‌دهد:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
redirect_uri=https%3A//developers.google.com/oauthplayground&
grant_type=authorization_code

ساختن مدرک DPoP

مراحل زیر نحوه ساختن اثبات DPoP بااستفاده از OpenSSL از خط فرمان را نشان می‌دهد:

  1. تولید جفت کلید EC P-256:
    openssl ecparam -name prime256v1 -genkey -noout -out dpop_private.pem
    openssl ec -in dpop_private.pem -pubout -out dpop_public.pem
  2. ایجاد سرصفحه DPoP:

    سرایند باید شامل ادعاهای typ، alg، و jwk (کلید عمومی) باشد. مقادیر x و y مختصات کدبندی‌شده Base64Url کلید عمومی EC شما هستند. این JSON را با Base64Url کدبندی کنید:

    {
      "typ":"dpop+jwt",
      "alg":"ES256",
      "jwk": {
        "kty":"EC",
        "x":"YOUR_PUBLIC_KEY_X",
        "y":"YOUR_PUBLIC_KEY_Y",
        "crv":"P-256"
      }
    }
  3. ایجاد بار داده DPoP:

    بار داده باید شامل jti (شناسه یکتا برای درخواست)، htm (روش HTTP، مثلاً POST)، htu (HTTP URI، مثلاً https://oauth2.googleapis.com/token)، و iat (زمان صدور) باشد. اگر در پاسخ به درخواست قبلی، یک nonce از سرور در سرصفحه DPoP-Nonce دریافت کردید، باید آن مقدار nonce را در ادعای nonce اضافه کنید. ادعای nonce برای تبادل کد مجوز اختیاری است و فقط زمانی استفاده می‌شود که سرایند DPoP-Nonce قبلاً دریافت شده باشد. این JSON را با Base64Url کدبندی کنید:

    {
      "jti":"JTI_VALUE",
      "htm":"POST",
      "htu":"https://oauth2.googleapis.com/token",
      "iat":YOUR_JWT_ISSUED_TIME,
      "nonce":"SERVER_PROVIDED_NONCE"
    }

    مقدار jti به نوع مبادله بستگی دارد:

    • برای تبادل کد مجوز، jti باید درهم‌سازی SHA256 کدبندی‌شده با Base64Url از کد مجوز باشد: "jti":"BASE64URL(SHA256(AUTHORIZATION_CODE))".
    • برای تبادل ژتون بازآوری، jti باید یک شناسه یکتا برای هر درخواست باشد: "jti":"YOUR_UNIQUE_PER_REQUEST_IDENTIFIER".
  4. امضا کردن مدرک:

    سرصفحه و بار داده کدگذاری‌شده را با نقطه (.) به‌هم متصل کنید، سپس نتیجه را با کلید خصوصی‌تان بااستفاده از ES256 امضا کنید. توجه داشته باشید که JWS نیاز دارد امضا در قالب R | S به‌هم‌پیوسته خام (۶۴ بایت برای P-256) باشد. اگر مستقیماً از OpenSSL استفاده می‌کنید، باید امضای پیش‌فرض ASN.1 DER-encoded را به این قالب خام تبدیل کنید.

تبادل موفق با پاسخ 200 OK حاوی نشان‌ها مشخص می‌شود. اگر درطول تبادل از مدرک DPoP معتبری استفاده شود، رمز بازآوری که Google برمی‌گرداند به کلید شما محدود خواهد شد، اما رمزهای دسترسی محدود نخواهند شد. کدهای دسترسی به‌جای DPoP، token_type مربوط به Bearer را حفظ خواهند کرد. علاوه‌براین، Google سرصفحه HTTP DPoP-Nonce را در پاسخ برمی‌گرداند. کارخواه شما باید این nonce را در حافظه نهان ذخیره کند و آن را در ادعای nonce مدرک DPoP در درخواست‌های بعدی (مثلاً هنگام تبادل کردن کد نوسازی برای کد دسترسی جدید، یا هنگام فراخوانی کردن میاناهای برنامه‌سازی کاربردی محافظت‌شده با DPoP) بگنجاند. بااستفاده از این عدد یک‌بارمصرف صادرشده زودهنگام، می‌توانید از خطای رفت‌وبرگشت اضافی (use_dpop_nonce) در درخواست بعدی‌تان جلوگیری کنید.

برای درخواست‌های مبادله کد که با کد بازآوری محدود به DPoP انجام می‌شوند، باید مدرک DPoP ارائه شود.

تبادل ناموفق زمانی رخ می‌دهد که سرایند DPoP در زمان موردانتظار وجود نداشته باشد، نامعتبر باشد، یا اگر مدرک از کلیدی متفاوت با کلید متصل به کد استفاده کند. در این موارد، سرور خطای 400 Bad Request برمی‌گرداند. اگر مدرک DPoP ادعاهای htm یا htu ناهماهنگ، iat منقضی، jti مجدداً استفاده‌شده، یا امضای نامعتبر داشته باشد، Google کد خطای invalid_dpop_proof برمی‌گرداند. اگر یک DPoP nonce لازم باشد، مثلاً درطول تبادل ژتون بازآوری، و اثبات DPoP فاقد ادعای nonce باشد، یا مقدار nonce برای سرور غیرقابل‌قبول باشد (مثلاً منقضی شده باشد، قبلاً استفاده شده باشد، یا نادرست باشد)، Google کد خطای use_dpop_nonce را به‌همراه سرصفحه HTTP‏ DPoP-Nonce حاوی یک nonce جدید برمی‌گرداند که می‌توانید در درخواست بعدی استفاده کنید. خطاهای دیگر ممکن است invalid_grant را برگرداند.

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

پاسخ حاوی فیلدهای زیر است:

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

تکه‌کد زیر نمونه‌ای از سرایندها و متن پاسخ موفقیت‌آمیز را هنگام استفاده از DPoP نشان می‌دهد:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/youtube.force-ssl",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

خطاها

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

invalid_grant

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

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

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

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

برای اطلاعات دقیق‌تر، نحوه مدیریت اجازه‌های ریزدانه را ببینید.

PHP

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

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

Python

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

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

Ruby

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

# User authorized the request. Now, check which scopes were granted.
if credentials.scope.include?(Google::Apis::YoutubeV3::AUTH_YOUTUBE_FORCE_SSL)
  # User authorized permission to see, edit, and permanently delete the
  # YouTube videos, ratings, comments and captions.
  # Calling the APIs, etc
else
  # User didn't authorize the 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/youtube.force-ssl'))
{
  // User authorized permission to see, edit, and permanently delete the
  // YouTube videos, ratings, comments and captions.
  // Calling the APIs, etc.
}
else
{
  // User didn't authorize read-only Drive activity permission.
  // Update UX and application accordingly
}

HTTP/REST

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

برای مثال، پاسخ نمونه کد دسترسی زیر نشان می‌دهد که کاربر به برنامه شما اجازه داده است ویدیوها، رتبه‌بندی‌ها، نظرات، و زیرنویس‌های ناشنوایان YouTube کاربر را ببیند، ویرایش کند، و برای همیشه حذف کند:

  {
    "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
    "expires_in": 3920,
    "token_type": "Bearer",
    "scope": "https://www.googleapis.com/auth/youtube.force-ssl",
    "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
  }

فراخوانی میاناهای برنامه‌سازی کاربردی Google

PHP

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

  1. اگر نیاز دارید یک کد دسترسی را به یک شیء جدید Google\Client اعمال کنید — برای مثال، اگر کد دسترسی را در یک جلسه کاربر ذخیره کرده‌اید — از روش setAccessToken استفاده کنید:
    $client->setAccessToken($access_token);
  2. یک شیء سرویس برای API که می‌خواهید فراخوانی کنید بسازید. با ارائه شیء Google\Client مجاز به سازنده برای API که می‌خواهید فراخوانی کنید، شیء سرویس می‌سازید. برای مثال، برای فراخوانی YouTube Data API:
    $youtube = new Google_Service_YouTube($client);
  3. بااستفاده از میانای ارائه‌شده توسط شیء سرویس، درخواست‌هایی به سرویس میانای برنامه‌سازی کاربردی ارسال کنید. برای مثال، برای بازیابی داده‌های مربوط به کانال YouTube کاربر مجاز:
    $channel = $youtube->channels->listChannels('snippet', array('mine' => $mine));

Python

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

  1. یک شیء سرویس برای API که می‌خواهید فراخوانی کنید بسازید. با فراخوانی روش build کتابخانه googleapiclient.discovery با نام و نسخه API و اطلاعات کاربری کاربر، یک شیء سرویس می‌سازید: برای مثال، برای فراخوانی نسخه ۳ YouTube Data API:
    from googleapiclient.discovery import build
    
    youtube = build('youtube', 'v3', credentials=credentials)
  2. بااستفاده از میانای ارائه‌شده توسط شیء سرویس، برای سرویس API درخواست کنید. برای مثال، برای بازیابی داده‌های مربوط به کانال YouTube کاربر مجاز:
    channel = youtube.channels().list(mine=True, part='snippet').execute()

Ruby

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

  1. یک شیء سرویس برای API که می‌خواهید فراخوانی کنید بسازید. برای مثال، برای فراخوانی نسخه ۳ از YouTube Data API:
    youtube = Google::Apis::YoutubeV3::YouTubeService.new
  2. اطلاعات کاربری را در سرویس تنظیم کنید:
    youtube.authorization = credentials
  3. بااستفاده از میانای ارائه‌شده توسط شیء سرویس، درخواست‌هایی به سرویس API ارسال کنید. برای مثال، برای بازیابی داده‌های مربوط به کانال YouTube کاربر مجاز:
    channel = youtube.list_channels(part, :mine => mine)

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

channel = youtube.list_channels(part, :mine => mine, options: { authorization: auth_client })

Node.js

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

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

// Example of using YouTube API to list channels.
var service = google.youtube('v3');
service.channels.list({
  auth: oauth2Client,
  part: 'snippet,contentDetails,statistics',
  forUsername: 'GoogleDevelopers'
}, function (err, response) {
  if (err) {
    console.log('The API returned an error: ' + err);
    return;
  }
  var channels = response.data.items;
  if (channels.length == 0) {
    console.log('No channel found.');
  } else {
    console.log('This channel\'s ID is %s. Its title is \'%s\', and ' +
      'it has %s views.',
      channels[0].id,
      channels[0].snippet.title,
      channels[0].statistics.viewCount);
  }
});

HTTP/REST

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

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

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

نمونه‌های HTTP GET

فراخوانی نقطه پایانی youtube.channels (YouTube Data API) بااستفاده از سرصفحه Authorization: Bearer HTTP ممکن است به‌صورت زیر باشد. توجه داشته باشید که باید کد دسترسی خودتان را مشخص کنید:

GET /youtube/v3/channels?part=snippet&mine=true HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

در اینجا فراخوانی به همان API برای کاربر اصیل بااستفاده از پارامتر رشته پُرسمان access_token ارائه شده است:

GET https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true

curl مثال

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

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true

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

curl https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true

نمونه کامل

مثال زیر یک شیء با قالب JSON را چاپ می‌کند که اطلاعاتی درباره کانال YouTube کاربر پس‌از اصالت‌سنجی و اعطای مجوز کاربر به برنامه برای مدیریت حساب YouTube کاربر نشان می‌دهد.

PHP

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

  1. در «کنسول API»، نشانی وب ماشین محلی را به فهرست نشانی‌های وب هدایت مجدد اضافه کنید. برای مثال، http://localhost:8080 را اضافه کنید.
  2. دایرکتوری جدیدی ایجاد کنید و به آن تغییر دهید. برای مثال:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. کتابخانه Google API Client برای PHP را بااستفاده از Composer نصب کنید:
    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']);
  
  $youtube = new Google_Service_YouTube($client);
  $channel = $youtube->channels->listChannels('snippet', array('mine' => $mine));
  echo json_encode($channel);
  
}
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_YOUTUBE::YOUTUBE_FORCE_SSL);

// 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();
  
  $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'];
}
?>

Python

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

  • آزمایش درخواست میانای برنامه‌سازی کاربردی: این پیوند به صفحه‌ای اشاره می‌کند که سعی می‌کند درخواست میانای برنامه‌سازی کاربردی نمونه‌ای را اجرا کند. درصورت لزوم، جریان صدور مجوز را شروع می‌کند. درصورت موفقیت‌آمیز بودن، صفحه پاسخ API را نمایش می‌دهد.
  • جریان اصالت‌سنجی را مستقیماً آزمایش کنید: این پیوند به صفحه‌ای اشاره می‌کند که تلاش می‌کند کاربر را ازطریق جریان صدور مجوز ارسال کند. برنامه برای ارسال درخواست‌های مجاز «میانای برنامه‌سازی کاربردی» ازطرف کاربر اجازه می‌خواهد.
  • لغو اعتبارنامه‌های فعلی: این پیوند به صفحه‌ای اشاره می‌کند که اجازه‌هایی را که کاربر قبلاً به برنامه اعطا کرده است لغو می‌کند.
  • پاک کردن اطلاعات اعتباری جلسه Flask: این پیوند اطلاعات اعتباری مجوز را که در جلسه Flask ذخیره شده است پاک می‌کند. این کار به شما امکان می‌دهد ببینید اگر کاربری که قبلاً به برنامه‌تان اجازه داده است بخواهد درخواست میانای برنامه‌سازی کاربردی را در جلسه جدیدی اجرا کند چه اتفاقی می‌افتد. همچنین به شما امکان می‌دهد پاسخ میانای برنامه‌سازی کاربردی را که برنامه‌تان درصورت لغو اجازه‌های اعطاشده به برنامه‌تان توسط کاربر دریافت می‌کند ببینید، و برنامه‌تان همچنان تلاش می‌کند درخواستی را با کد دسترسی لغوشده مجاز کند.
# -*- coding: utf-8 -*-

import os
import flask
import json
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/youtube.force-ssl']
API_SERVICE_NAME = 'youtube'
API_VERSION = 'v3'

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('/test')
def test_api_request():
  if 'credentials' not in flask.session:
  return flask.redirect('authorize')

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

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

  channel = youtube.channels().list(mine=True, part='snippet').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(**channel)
@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
  
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.redirect(flask.url_for('test_api_request'))
  
@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.')

  # Load client secrets from the server-side file.
  with open(CLIENT_SECRETS_FILE, 'r') as f:
      client_config = json.load(f)['web']

  # Load user-specific credentials from the session.
  session_credentials = flask.session['credentials']

  # Reconstruct the credentials object.
  credentials = google.oauth2.credentials.Credentials(
      refresh_token=session_credentials.get('refresh_token'),
      scopes=session_credentials.get('granted_scopes'),
      token=session_credentials.get('token'),
      client_id=client_config.get('client_id'),
      client_secret=client_config.get('client_secret'),
      token_uri=client_config.get('token_uri'))

  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:
    # Clear the user's session credentials after successful revocation
    if 'credentials' in flask.session:
        del flask.session['credentials']
        del flask.session['features']
    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,
          'granted_scopes': credentials.granted_scopes}

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="/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)

Ruby

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

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

require 'google/apis/youtube_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 retrieving data about the user's YouTube channel.
  scope = 'Google::Apis::YoutubeV3::AUTH_YOUTUBE_FORCE_SSL'

  # 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 read-only YouTube Data API permission.
  # Example of using YouTube Data API to list user's YouTube channel
  youtube = Google::Apis::YoutubeV3::YouTubeService.new
  channel = youtube.list_channels(part, :mine => mine, options: { authorization: auth_client })
  
  "<pre>#{JSON.pretty_generate(channel.to_h)}</pre>"
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»، نشانی وب دستگاه محلی را به فهرست نشانی‌های وب تغییرمسیر اضافه کنید. برای مثال، http://localhost را اضافه کنید.
  2. مطمئن شوید که LTS نگهداری، LTS فعال، یا نسخه پخش فعلی Node.js را نصب کرده باشید.
  3. فهرست راهنمای جدیدی ایجاد کنید و به آن بروید. برای مثال:
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. کتابخانه کارخواه Google API را برای 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 YouTube API
const scopes = [
  'https://www.googleapis.com/auth/youtube.force-ssl'
];

/* 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;
      
      // Example of using YouTube API to list channels.
      var service = google.youtube('v3');
      service.channels.list({
        auth: oauth2Client,
        part: 'snippet,contentDetails,statistics',
        forUsername: 'GoogleDevelopers'
      }, function (err, response) {
        if (err) {
          console.log('The API returned an error: ' + err);
          return;
        }
        var channels = response.data.items;
        if (channels.length == 0) {
          console.log('No channel found.');
        } else {
          console.log('This channel\'s ID is %s. Its title is \'%s\', and ' +
            'it has %s views.',
            channels[0].id,
            channels[0].snippet.title,
            channels[0].statistics.viewCount);
        }
      });
    }
  });

  // 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

این نمونه Python از چارچوب Flask و کتابخانه Requests برای نمایش جریان وب OAuth 2.0 استفاده می‌کند. توصیه می‌کنیم برای این جریان از «کتابخانه کارخواه Google API برای Python» استفاده کنید. (مثال در برگه 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 YouTube API
SCOPE = 'https://www.googleapis.com/auth/youtube.force-ssl'

# 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: 
    headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
    req_uri = 'https://www.googleapis.com/youtube/v3/channels/list'
    r = requests.get(req_uri, headers=headers)
    return r.text 

@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» مراجعه کنید.

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

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

میزبان

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

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

    شناسه منبع یکسان تغییرمسیر نمی‌تواند حاوی زیرمؤلفه userinfo باشد.

    مسیر

    شناسه منبع یکسان (URI) تغییرمسیر نمی‌تواند حاوی پیمایش مسیر (که به آن بازگشت دایرکتوری نیز می‌گویند) باشد، که با “/..” یا “\..” یا کدبندی نشانی وب آن‌ها نشان داده می‌شود.

    پُرسمان

    نشانی‌های وب هدایت نباید حاوی هدایت‌های باز باشند.

    Fragment

    نشانی‌های وب هدایت مجدد نمی‌توانند شامل عنصر بخش باشند.

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

    مجوزدهی افزایشی

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

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

    در این حالت، هنگام ورود به سیستم، ممکن است برنامه به دسترسی به هیچ دامنه‌ای نیاز نداشته باشد یا آن را درخواست نکند. اما اگر کاربر بخواهد به ویدیویی امتیاز دهد، ویدیویی را به فهرست پخش اضافه کند، یا کنش دیگری در YouTube انجام دهد، برنامه می‌تواند درخواست دسترسی به دامنه https://www.googleapis.com/auth/youtube.force-ssl را بدهد. به‌طور مشابه، اگر کاربر بخواهد رویداد تقویم اضافه کند، برنامه می‌تواند درخواست دسترسی به دامنه https://www.googleapis.com/auth/calendar را بدهد.

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

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

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

    نمونه‌های کد مختص زبان در مرحله ۱: تنظیم کردن مجوز هدایت کردن به سرور OAuth 2.0 از Google همگی از مجوز افزایشی استفاده می‌کنند. نمونه کدهای زیر همچنین کدی را نشان می‌دهند که باید برای استفاده از مجوز افزایشی اضافه کنید.

    PHP

    $client->setIncludeGrantedScopes(true);

    Python

    در Python، آرگومان کلیدواژه 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')

    Ruby

    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

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

    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
    
          

    Refresh 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 برای دسترسی به «میاناهای برنامه‌سازی کاربردی Google» ازطرف کاربر در زمانی که کاربر آفلاین است استفاده کنید. شیء کارخواه کد دسترسی را درصورت نیاز بازآوری خواهد کرد.

    Python

    در Python، آرگومان کلیدواژه 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 برای دسترسی به «میاناهای برنامه‌سازی کاربردی Google» ازطرف کاربر در زمانی که کاربر آفلاین است استفاده کنید. شیء کارخواه کد دسترسی را درصورت نیاز بازآوری خواهد کرد.

    Ruby

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

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

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

    Node.js

    اگر برنامه‌تان به دسترسی آفلاین به میانای برنامه‌سازی کاربردی Google نیاز دارد، نوع دسترسی کارخواه میانای برنامه‌سازی کاربردی را روی 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 برای دسترسی به «میاناهای برنامه‌سازی کاربردی 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);
    });

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

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

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

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

    HTTP/REST

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

    نام مقدار
    client_id شناسه مشتری به‌دست‌آمده از کنسول API.
    client_secret اختیاری

    رمز کارخواه به‌دست‌آمده از کنسول API.

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

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

    سرایند الزامی شرح
    DPoP اختیاری اثبات DPoP یک JWT است که مالکیت کلید خصوصی را اثبات می‌کند. این سرصفحه است، نه پارامتر. اگر ارائه شود، نشان‌های برگشتی به این کلید محدود می‌شوند. برای هر درخواست باید مدرک جدید و منحصربه‌فردی تولید شود و باید شامل ادعاهای htm (روش HTTP) و htu (نشانی وب HTTP) باشد که با درخواست مطابقت داشته باشد.

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

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

    برای استفاده از DPoP با ژتون بازآوری، باید JWT اثبات DPoP جدید و منحصربه‌فردی برای درخواست تولید کنید. برای دریافت دستورالعمل‌های گام‌به‌گام درباره تولید جفت کلید و ساختن JWT، به ساختن مدرک DPoP مراجعه کنید.

    تبادل موفق با پاسخ 200 OK حاوی یک کد دسترسی جدید نشان داده می‌شود. وقتی از DPoP استفاده می‌شود، token_type Bearer است. پاسخ موفق تأیید می‌کند مدرک DPoP برای کد نوسازی پذیرفته شده است. Google همچنین ممکن است سرصفحه HTTP جدید DPoP-Nonce را در پاسخ برگرداند؛ درصورت برگردانده شدن، کارخواه شما باید این nonce را در حافظه نهان ذخیره کند و آن را در ادعای nonce اثبات DPoP در درخواست‌های بعدی لحاظ کند.

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

    تکه کد زیر سرصفحه‌ها و متن پاسخ موفقیت‌آمیز نمونه‌ای را هنگام استفاده از DPoP نشان می‌دهد:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI
    
    {
      "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
      "expires_in": 3920,
      "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
      "token_type": "Bearer"
    }

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

    ابطال کد

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

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

    PHP

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

    $client->revokeToken();

    Python

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

    Ruby

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

    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 درطول جریان موافقت دردسترس است و به کاربران امکان می‌دهد برای مدت محدودی دسترسی اعطا کنند. یک نمونه از این ابزارها Data Portability API است که امکان انتقال یک‌باره داده‌ها را فراهم می‌کند.

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

    پیاده‌سازی «محافظت بین‌حسابی»

    یکی از اقدامات تکمیلی که باید برای محافظت از حساب‌های کاربران خود انجام دهید، پیاده‌سازی «محافظت بین‌حسابی» بااستفاده از «سرویس محافظت بین‌حسابی» 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

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