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

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

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

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

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

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

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

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

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

پیش نیازها

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

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

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

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

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

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

  1. روی Create Client کلیک کنید.
  2. نوع برنامه کاربردی وب را انتخاب کنید.
  3. فرم را پر کنید و روی ایجاد کلیک کنید. برنامه هایی که از زبان ها و فریم ورک هایی مانند PHP، جاوا، پایتون، روبی و دات نت استفاده می کنند باید URI های مجاز تغییر مسیر را مشخص کنند. URI های تغییر مسیر، نقاط پایانی هستند که سرور OAuth 2.0 می تواند پاسخ ها را به آنها ارسال کند. این نقاط پایانی باید از قوانین اعتبارسنجی Google پیروی کنند.

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

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

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

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

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

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

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

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

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

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

PHP

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

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

    composer require google/apiclient:^2.15.0

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

پایتون

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

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

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

روبی

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

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

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

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

    gem install sinatra

Node.js

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

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

    npm install googleapis crypto express express-session

HTTP/REST

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

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

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

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

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

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

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

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

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

PHP

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

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

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

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\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);

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

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

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

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

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

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

پایتون

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

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

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

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

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

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

روبی

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

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

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

require 'google/apis/drive_v3'
require 'google/apis/calendar_v3'

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

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

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

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

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

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

Node.js

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

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

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

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

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

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

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

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

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

HTTP/REST

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

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

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

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

redirect_uri مورد نیاز

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

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

response_type مورد نیاز

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

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

scope مورد نیاز

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

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

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

access_type توصیه می شود

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

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

state توصیه می شود

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

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

include_granted_scopes اختیاری

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

login_hint اختیاری

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

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

prompt اختیاری

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

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

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

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

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

PHP

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

پایتون

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

return flask.redirect(authorization_url)

روبی

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

Node.js

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

HTTP/REST

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

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

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

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

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

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

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

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

خطاها

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

admin_policy_enforced

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

disallowed_useragent

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

اندروید

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

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

iOS

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

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

org_internal

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

invalid_client

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

invalid_grant

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

redirect_uri_mismatch

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

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

invalid_request

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

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

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

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

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

یک پاسخ خطا:

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

پاسخ کد مجوز:

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

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

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

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

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

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

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

PHP

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

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

پایتون

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

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

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

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

روبی

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

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

Node.js

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

const url = require('url');

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

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

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

HTTP/REST

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

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

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

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

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

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

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

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

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

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

خطاها

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

invalid_grant

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

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

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

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

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

PHP

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

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

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

پایتون

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

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

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

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

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

  return features

روبی

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

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

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

Node.js

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

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

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

HTTP/REST

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

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

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

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

PHP

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

  1. اگر نیاز به اعمال یک نشانه دسترسی به یک شی جدید Google\Client دارید - برای مثال، اگر نشانه دسترسی را در یک جلسه کاربر ذخیره کرده اید - از روش setAccessToken استفاده کنید:
    $client->setAccessToken($access_token);
  2. یک شیء سرویس برای API که می خواهید فراخوانی کنید بسازید. شما با ارائه یک شیء مجاز Google\Client به سازنده برای API که می خواهید فراخوانی کنید، یک شیء سرویس می سازید. به عنوان مثال، برای فراخوانی Drive API:
    $drive = new Google\Service\Drive($client);
  3. با استفاده از رابط ارائه شده توسط شی سرویس، درخواست هایی را به سرویس API ارسال کنید. به عنوان مثال، برای فهرست کردن فایل‌ها در Google Drive کاربر تأیید شده:
    $files = $drive->files->listFiles(array());

پایتون

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

  1. یک شیء سرویس برای API که می خواهید فراخوانی کنید بسازید. شما با فراخوانی روش build کتابخانه googleapiclient.discovery با نام و نسخه API و اعتبار کاربر، یک شیء سرویس می‌سازید: به عنوان مثال، برای فراخوانی نسخه 3 Drive API:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. با استفاده از رابط ارائه شده توسط شی سرویس، درخواست هایی را به سرویس API ارسال کنید. به عنوان مثال، برای فهرست کردن فایل‌ها در Google Drive کاربر تأیید شده:
    files = drive.files().list().execute()

روبی

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

  1. یک شیء سرویس برای API که می خواهید فراخوانی کنید بسازید. برای مثال، برای فراخوانی نسخه 3 Drive API:
    drive = Google::Apis::DriveV3::DriveService.new
  2. اعتبارنامه را روی سرویس تنظیم کنید:
    drive.authorization = credentials
  3. با استفاده از رابط ارائه شده توسط شی سرویس، درخواست هایی را به سرویس API ارسال کنید. به عنوان مثال، برای فهرست کردن فایل‌ها در Google Drive کاربر تأیید شده:
    files = drive.list_files

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

files = drive.list_files(options: { authorization: credentials })

Node.js

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

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

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

HTTP/REST

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

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

نمونه های HTTP GET

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

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

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

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

نمونه های curl

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

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

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

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

مثال کامل

مثال زیر پس از احراز هویت کاربر و رضایت برنامه برای دسترسی به فراداده Drive کاربر، فهرستی با فرمت JSON از فایل‌ها را در Google Drive کاربر چاپ می‌کند.

PHP

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

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

index.php

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

session_start();

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

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

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

oauth2callback.php

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

session_start();

$client = new Google\Client();

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

// Required, to set the scope value, call the addScope function.
$client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);

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

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

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

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

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

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

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

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

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

پایتون

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

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

import os
import flask
import requests

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

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

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

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

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

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

  features = flask.session['features']

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

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

    files = drive.files().list().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(**files)
  else:
    # User didn't authorize read-only Drive activity permission.
    # Update UX and application accordingly
    return '<p>Drive feature is not enabled.</p>'

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

      features = flask.session['features']

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

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

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

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

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

  return flask.redirect(authorization_url)

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

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

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

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

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

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

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

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

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

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

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

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

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

  return features

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

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

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

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

روبی

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

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

require 'google/apis/drive_v3'
require 'google/apis/calendar_v3'

require 'sinatra'

configure do
  enable :sessions

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

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

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

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

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

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

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

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

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

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

Node.js

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

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

main.js

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

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

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

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

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

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

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

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

    res.redirect(authorizationUrl);
  });

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

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

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

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

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

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

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

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

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


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

HTTP/REST

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

import json
import flask
import requests

app = flask.Flask(__name__)

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

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

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

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

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

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

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

  return r

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

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

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

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

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

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

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

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

میزبان

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

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

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

    مسیر

    تغییر مسیر URIS نمی تواند حاوی یک مسیر مسیری باشد (که به آن Backtracking Directory نیز گفته می شود) ، که توسط “/..” یا “\..” یا رمزگذاری URL آنها نشان داده شده است.

    پرس و جو

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

    قطعه

    URIS تغییر مسیر نمی تواند حاوی مؤلفه قطعه باشد.

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

    مجوز افزایشی

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

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

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

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

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

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

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

    PHP

    $client->setIncludeGrantedScopes(true);

    پایتون

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

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

    روبی

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

    Node.js

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

    http/استراحت

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

    تازه کردن یک نشانه دسترسی (دسترسی آفلاین)

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

    • اگر از یک کتابخانه مشتری Google API استفاده می کنید ، شیء مشتری تا زمانی که آن شیء را برای دسترسی آفلاین پیکربندی می کنید ، نشانه دسترسی را تازه می کند.
    • اگر از کتابخانه مشتری استفاده نمی کنید ، باید هنگام هدایت کاربر به سرور OAUTH 2.0 Google ، پارامتر پرس و جو access_type HTTP را به offline تنظیم کنید. در این حالت ، سرور مجوز Google هنگام تبادل یک کد مجوز برای یک نشانه دسترسی ، یک نشانه تازه را برمی گرداند. سپس ، اگر نشانه دسترسی منقضی شود (یا در هر زمان دیگری) ، می توانید از یک نشانه تازه برای بدست آوردن یک نشانه دسترسی جدید استفاده کنید.

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

    برنامه های وب سمت سرور ، برنامه های نصب شده و دستگاه ها همه در طی فرایند مجوز نشانه های تازه سازی را بدست می آورند. نشانه های تازه سازی به طور معمول در برنامه های وب طرف مشتری (JavaScript) استفاده نمی شوند.

    PHP

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

    $client->setAccessType("offline");

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

    پایتون

    در پایتون ، آرگومان کلیدی 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 Client برای دسترسی به Google API ها از طرف کاربر استفاده کنید. شیء مشتری در صورت لزوم نشانه دسترسی را تازه می کند.

    روبی

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

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

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

    Node.js

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

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

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

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

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

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

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

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

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

    http/استراحت

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

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

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

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

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

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

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

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

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

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

    PHP

    برای ابطال برنامه ای ، با revokeToken() تماس بگیرید:

    $client->revokeToken();

    پایتون

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

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

    روبی

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

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

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

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

    Node.js

    برای ابطال برنامه نویسی ، یک درخواست پست HTTPS را به نقطه پایانی /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/استراحت

    برای ابطال برنامه ای ، برنامه شما درخواست 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 Select در طول جریان رضایت در دسترس است و به کاربران این امکان را می دهد که برای مدت زمان محدود دسترسی را اعطا کنند. به عنوان مثال ، API قابلیت حمل داده است که انتقال یک بار داده را امکان پذیر می کند.

    هنگامی که یک کاربر دسترسی مبتنی بر زمان برنامه شما را اعطا می کند ، Token Refresh پس از مدت زمان مشخص منقضی می شود. توجه داشته باشید که نشانه های تازه سازی ممکن است قبلاً در شرایط خاص باطل شوند. برای جزئیات بیشتر به این موارد مراجعه کنید. قسمت 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

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

    ،

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

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

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

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

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

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

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

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

    پیش نیازها

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

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

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

    1. در .
    2. را لیست کلیه API های موجود ، گروه بندی شده بر اساس خانواده محصول و محبوبیت. اگر API که می خواهید فعال کنید در لیست قابل مشاهده نیست ، از جستجو برای یافتن آن استفاده کنید ، یا روی مشاهده همه در خانواده محصولی که متعلق به آن است کلیک کنید.
    3. API را که می خواهید فعال کنید انتخاب کنید ، سپس بر روی دکمه Enable کلیک کنید.

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

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

    1. روی ایجاد مشتری کلیک کنید.
    2. نوع برنامه کاربردی وب را انتخاب کنید.
    3. فرم را پر کرده و روی ایجاد کلیک کنید. برنامه هایی که از زبانها و چارچوب هایی مانند PHP ، Java ، Python ، Ruby و .NET استفاده می کنند ، باید URI های تغییر مسیر مجاز را مشخص کنند. URI های تغییر مسیر نقاط پایانی هستند که سرور OAUTH 2.0 می تواند پاسخ ارسال کند. این نقاط پایانی باید به قوانین اعتبار سنجی گوگل رعایت کنند.

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

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

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

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

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

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

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

    سند OAUTH 2.0 API Scopes شامل لیست کاملی از Scopes است که ممکن است برای دسترسی به Google API استفاده کنید.

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

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

    PHP

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

    • PHP 8.0 یا بیشتر با رابط خط فرمان (CLI) و پسوند JSON نصب شده است.
    • ابزار مدیریت وابستگی آهنگساز .
    • کتابخانه مشتری Google APIS برای PHP:

      composer require google/apiclient:^2.15.0

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

    پایتون

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

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

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

    روبی

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

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

      gem install googleauth
    • کتابخانه های مشتری برای درایو و تقویم Google API:

      gem install google-apis-drive_v3 google-apis-calendar_v3
    • چارچوب برنامه وب Sinatra Ruby.

      gem install sinatra

    Node.js

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

    • LTS تعمیر و نگهداری ، LTS فعال یا انتشار فعلی Node.js.
    • مشتری Google APIS Node.js:

      npm install googleapis crypto express express-session

    http/استراحت

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

    به دست آوردن نشانه های دسترسی OAUTH 2.0

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

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

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

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

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

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

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

    PHP

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

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

    به عنوان مثال ، این کد درخواست دسترسی فقط خواندنی و آفلاین به فوق داده Google Drive کاربر و رویدادهای تقویم است:

    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\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);
    
    // Required, call the setRedirectUri function to specify a valid redirect URI for the
    // provided client_id
    $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
    
    // Recommended, offline access will give you both an access and refresh token so that
    // your app can refresh the access token without user interaction.
    $client->setAccessType('offline');
    
    // Recommended, call the setState function. Using a state value can increase your assurance that
    // an incoming connection is the result of an authentication request.
    $client->setState($sample_passthrough_value);
    
    // Optional, if your application knows which user is trying to authenticate, it can use this
    // parameter to provide a hint to the Google Authentication Server.
    $client->setLoginHint('hint@example.com');
    
    // Optional, call the setPrompt function to set "consent" will prompt the user for consent
    $client->setPrompt('consent');
    
    // Optional, call the setIncludeGrantedScopes function with true to enable incremental
    // authorization
    $client->setIncludeGrantedScopes(true);

    پایتون

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

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

    به عنوان مثال ، این کد درخواست دسترسی فقط خواندنی و آفلاین به فوق داده Google Drive کاربر و رویدادهای تقویم است:

    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/drive.metadata.readonly',
                'https://www.googleapis.com/auth/calendar.readonly'])
    
    # Required, indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required. The value must exactly
    # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
    # configured in the API Console. If this value doesn't match an authorized URI,
    # you will get a 'redirect_uri_mismatch' error.
    flow.redirect_uri = 'https://www.example.com/oauth2callback'
    
    # Generate URL for request to Google's OAuth 2.0 server.
    # Use kwargs to set optional request parameters.
    authorization_url, state = flow.authorization_url(
        # Recommended, enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Optional, enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true',
        # Optional, if your application knows which user is trying to authenticate, it can use this
        # parameter to provide a hint to the Google Authentication Server.
        login_hint='hint@example.com',
        # Optional, set prompt to 'consent' will prompt the user for consent
        prompt='consent')

    روبی

    از پرونده client_secrets.json که ایجاد کرده اید برای پیکربندی یک شی مشتری در برنامه خود استفاده کنید. هنگامی که یک شیء مشتری را پیکربندی می کنید ، Scopes را که برنامه شما برای دسترسی به آن دسترسی دارد ، همراه با URL به نقطه انتهایی برنامه شما ، که پاسخ از سرور OAUTH 2.0 را بر عهده دارد ، مشخص می کنید.

    به عنوان مثال ، این کد درخواست دسترسی فقط خواندنی و آفلاین به فوق داده Google Drive کاربر و رویدادهای تقویم است:

    require 'googleauth'
    require 'googleauth/web_user_authorizer'
    require 'googleauth/stores/redis_token_store'
    
    require 'google/apis/drive_v3'
    require 'google/apis/calendar_v3'
    
    # Required, call the from_file method to retrieve the client ID from a
    # client_secret.json file.
    client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')
    
    # Required, scope value 
    # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
             'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']
    
    # Required, Authorizers require a storage instance to manage long term persistence of
    # access and refresh tokens.
    token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
    
    # Required, indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required. The value must exactly
    # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
    # configured in the API Console. If this value doesn't match an authorized URI,
    # you will get a 'redirect_uri_mismatch' error.
    callback_uri = '/oauth2callback'
    
    # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
    # from the client_secret.json file. To get these credentials for your application, visit
    # https://console.cloud.google.com/apis/credentials.
    authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope,
                                                    token_store, callback_uri)

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

    Node.js

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

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

    const {google} = require('googleapis');
    const crypto = require('crypto');
    const express = require('express');
    const session = require('express-session');
    
    /**
     * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
     * from the client_secret.json file. To get these credentials for your application, visit
     * https://console.cloud.google.com/apis/credentials.
     */
    const oauth2Client = new google.auth.OAuth2(
      YOUR_CLIENT_ID,
      YOUR_CLIENT_SECRET,
      YOUR_REDIRECT_URL
    );
    
    // Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    const scopes = [
      'https://www.googleapis.com/auth/drive.metadata.readonly',
      'https://www.googleapis.com/auth/calendar.readonly'
    ];
    
    // Generate a secure random state value.
    const state = crypto.randomBytes(32).toString('hex');
    
    // Store state in the session
    req.session.state = state;
    
    // Generate a url that asks permissions for the Drive activity and Google Calendar scope
    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true,
      // Include the state parameter to reduce the risk of CSRF attacks.
      state: state
    });

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

    http/استراحت

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

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

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

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

    redirect_uri مورد نیاز

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

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

    response_type مورد نیاز

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

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

    scope مورد نیاز

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

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

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

    access_type توصیه می شود

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

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

    state توصیه می شود

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

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

    include_granted_scopes اختیاری

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

    login_hint اختیاری

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

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

    prompt اختیاری

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

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

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

    مرحله 2: به سرور OAUTH 2.0 Google تغییر مسیر دهید

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

    PHP

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

    پایتون

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

    return flask.redirect(authorization_url)

    روبی

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

    Node.js

    1. برای درخواست دسترسی از سرور OAUTH 2.0 Google ، از authorizationUrl URL تولید generateAuthUrl استفاده کنید.
    2. کاربر را به authorizationUrl تغییر دهید.
      res.redirect(authorizationUrl);

    http/استراحت

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

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

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

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

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

    مرحله 3: Google کاربر را برای رضایت ترغیب می کند

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

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

    خطاها

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

    admin_policy_enforced

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

    disallowed_useragent

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

    اندروید

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

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

    iOS

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

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

    org_internal

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

    invalid_client

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

    invalid_grant

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

    redirect_uri_mismatch

    redirect_uri که در درخواست مجوز گذشت ، با URI تغییر مسیر مجاز برای شناسه مشتری OAuth مطابقت ندارد. بررسی URI های تغییر مسیر مجاز در .

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

    invalid_request

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

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

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

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

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

    یک پاسخ خطا:

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

    پاسخ کد مجوز:

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

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

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

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

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

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

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

    PHP

    To exchange an authorization code for an access token, use the fetchAccessTokenWithAuthCode method:

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

    پایتون

    On your callback page, use the google-auth library to verify the authorization server response. Then, use the flow.fetch_token method to exchange the authorization code in that response for an access token:

    state = flask.session['state']
    flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
        'client_secret.json',
        scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'],
        state=state)
    flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
    
    authorization_response = flask.request.url
    flow.fetch_token(authorization_response=authorization_response)
    
    # Store the credentials in the session.
    # ACTION ITEM for developers:
    #     Store user's access and refresh tokens in your data store if
    #     incorporating this code into your real app.
    credentials = flow.credentials
    flask.session['credentials'] = {
        'token': credentials.token,
        'refresh_token': credentials.refresh_token,
        'token_uri': credentials.token_uri,
        'client_id': credentials.client_id,
        'client_secret': credentials.client_secret,
        'granted_scopes': credentials.granted_scopes}

    روبی

    On your callback page, use the googleauth library to verify the authorization server response. Use the authorizer.handle_auth_callback_deferred method to save the authorization code and redirect back to the URL that originally requested authorization. This 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

    Node.js

    To exchange an authorization code for an access token, use the getToken method:

    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

    To exchange an authorization code for an access token, call the https://oauth2.googleapis.com/token endpoint and set the following parameters:

    فیلدها
    client_id The client ID obtained from the .
    client_secret The client secret obtained from the .
    code The authorization code returned from the initial request.
    grant_type As defined in the OAuth 2.0 specification , this field's value must be set to authorization_code .
    redirect_uri One of the redirect URIs listed for your project in the for the given client_id .

    The following snippet shows a sample request:

    POST /token HTTP/1.1
    Host: oauth2.googleapis.com
    Content-Type: application/x-www-form-urlencoded
    
    code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
    client_id=your_client_id&
    client_secret=your_client_secret&
    redirect_uri=https%3A//oauth2.example.com/code&
    grant_type=authorization_code

    Google responds to this request by returning a JSON object that contains a short-lived access token and a refresh token. Note that the refresh token is only returned if your application set the access_type parameter to offline in the initial request to Google's authorization server .

    The response contains the following fields:

    فیلدها
    access_token The token that your application sends to authorize a Google API request.
    expires_in The remaining lifetime of the access token in seconds.
    refresh_token A token that you can use to obtain a new access token. Refresh tokens are valid until the user revokes access or the refresh token expires. Again, this field is only present in this response if you set the access_type parameter to offline in the initial request to Google's authorization server.
    refresh_token_expires_in The remaining lifetime of the refresh token in seconds. This value is only set when the user grants time-based access .
    scope The scopes of access granted by the access_token expressed as a list of space-delimited, case-sensitive strings.
    token_type The type of token returned. At this time, this field's value is always set to Bearer .

    The following snippet shows a sample response:

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

    خطاها

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

    invalid_grant

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

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

    When requesting multiple permissions (scopes), users may not grant your app access to all of them. Your app must verify which scopes were actually granted and gracefully handle situations where some permissions are denied, typically by disabling the features that rely on those denied scopes.

    با این حال، استثناهایی وجود دارد. Google Workspace Enterprise apps with domain-wide delegation of authority , or apps marked as Trusted , bypass the granular permissions consent screen. For these apps, users won't see the granular permission consent screen. Instead, your app will either receive all requested scopes or none.

    For more detailed information, see How to handle granular permissions .

    PHP

    To check which scopes the user has granted, use the getGrantedScope() method:

    // Space-separated string of granted scopes if it exists, otherwise null.
    $granted_scopes = $client->getOAuth2Service()->getGrantedScope();
    
    // Determine which scopes user granted and build a dictionary
    $granted_scopes_dict = [
      'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
      'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
    ];

    پایتون

    The returned credentials object has a granted_scopes property, which is a list of scopes the user has granted to your app.

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

    The following function checks which scopes the user has granted to your app.

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

    روبی

    When requesting multiple scopes at once, check which scopes were granted through the scope property of the credentials object.

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

    Node.js

    When requesting multiple scopes at once, check which scopes were granted through the scope property of the tokens object.

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

    HTTP/REST

    To check whether the user has granted your application access to a particular scope, exam the scope field in the access token response. The scopes of access granted by the access_token expressed as a list of space-delimited, case-sensitive strings.

    For example, the following sample access token response indicates that the user has granted your application access to the read-only Drive activity and Calendar events permissions:

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

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

    PHP

    Use the access token to call Google APIs by completing the following steps:

    1. If you need to apply an access token to a new Google\Client object — for example, if you stored the access token in a user session — use the setAccessToken method:
      $client->setAccessToken($access_token);
    2. Build a service object for the API that you want to call. You build a service object by providing an authorized Google\Client object to the constructor for the API you want to call. For example, to call the Drive API:
      $drive = new Google\Service\Drive($client);
    3. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
      $files = $drive->files->listFiles(array());

    پایتون

    After obtaining an access token, your application can use that token to authorize API requests on behalf of a given user account or service account. Use the user-specific authorization credentials to build a service object for the API that you want to call, and then use that object to make authorized API requests.

    1. Build a service object for the API that you want to call. You build a service object by calling the googleapiclient.discovery library's build method with the name and version of the API and the user credentials: For example, to call version 3 of the Drive API:
      from googleapiclient.discovery import build
      
      drive = build('drive', 'v2', credentials=credentials)
    2. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
      files = drive.files().list().execute()

    روبی

    After obtaining an access token, your application can use that token to make API requests on behalf of a given user account or service account. Use the user-specific authorization credentials to build a service object for the API that you want to call, and then use that object to make authorized API requests.

    1. Build a service object for the API that you want to call. For example, to call version 3 of the Drive API:
      drive = Google::Apis::DriveV3::DriveService.new
    2. Set the credentials on the service:
      drive.authorization = credentials
    3. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
      files = drive.list_files

    Alternately, authorization can be provided on a per-method basis by supplying the options parameter to a method:

    files = drive.list_files(options: { authorization: credentials })

    Node.js

    After obtaining an access token and setting it to the OAuth2 object, use the object to call Google APIs. Your application can use that token to authorize API requests on behalf of a given user account or service account. Build a service object for the API that you want to call. For example, the following code uses the Google Drive API to list filenames in the user's Drive.

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

    HTTP/REST

    After your application obtains an access token, you can use the token to make calls to a Google API on behalf of a given user account if the scope(s) of access required by the API have been granted. To do this, include the access token in a request to the API by including either an access_token query parameter or an Authorization HTTP header Bearer value. When possible, the HTTP header is preferable, because query strings tend to be visible in server logs. In most cases you can use a client library to set up your calls to Google APIs (for example, when calling the Drive Files API ).

    You can try out all the Google APIs and view their scopes at the OAuth 2.0 Playground .

    HTTP GET examples

    A call to the drive.files endpoint (the Drive Files API) using the Authorization: Bearer HTTP header might look like the following. Note that you need to specify your own access token:

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

    Here is a call to the same API for the authenticated user using the access_token query string parameter:

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

    curl examples

    You can test these commands with the curl command-line application. Here's an example that uses the HTTP header option (preferred):

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

    Or, alternatively, the query string parameter option:

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

    مثال کامل

    The following example prints a JSON-formatted list of files in a user's Google Drive after the user authenticates and gives consent for the application to access the user's Drive metadata.

    PHP

    To run this example:

    1. در , add the URL of the local machine to the list of redirect URLs. For example, add http://localhost:8080 .
    2. Create a new directory and change to it. به عنوان مثال:
      mkdir ~/php-oauth2-example
      cd ~/php-oauth2-example
    3. Install the Google API Client Library for PHP using Composer :
      composer require google/apiclient:^2.15.0
    4. Create the files index.php and oauth2callback.php with the following content.
    5. Run the example with the PHP's built-in test web server:
      php -S localhost:8080 ~/php-oauth2-example

    index.php

    <?php
    require_once __DIR__.'/vendor/autoload.php';
    
    session_start();
    
    $client = new Google\Client();
    $client->setAuthConfig('client_secret.json');
    
    // User granted permission as an access token is in the session.
    if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
    {
      $client->setAccessToken($_SESSION['access_token']);
      
      // Check if user granted Drive permission
      if ($_SESSION['granted_scopes_dict']['Drive']) {
        echo "Drive feature is enabled.";
        echo "</br>";
        $drive = new Drive($client);
        $files = array();
        $response = $drive->files->listFiles(array());
        foreach ($response->files as $file) {
            echo "File: " . $file->name . " (" . $file->id . ")";
            echo "</br>";
        }
      } else {
        echo "Drive feature is NOT enabled.";
        echo "</br>";
      }
    
       // Check if user granted Calendar permission
      if ($_SESSION['granted_scopes_dict']['Calendar']) {
        echo "Calendar feature is enabled.";
        echo "</br>";
      } else {
        echo "Calendar feature is NOT enabled.";
        echo "</br>";
      }
    }
    else
    {
      // Redirect users to outh2call.php which redirects users to Google OAuth 2.0
      $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
      header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }
    ?>

    oauth2callback.php

    <?php
    require_once __DIR__.'/vendor/autoload.php';
    
    session_start();
    
    $client = new Google\Client();
    
    // Required, call the setAuthConfig function to load authorization credentials from
    // client_secret.json file.
    $client->setAuthConfigFile('client_secret.json');
    $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF']);
    
    // Required, to set the scope value, call the addScope function.
    $client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);
    
    // Enable incremental authorization. Recommended as a best practice.
    $client->setIncludeGrantedScopes(true);
    
    // Recommended, offline access will give you both an access and refresh token so that
    // your app can refresh the access token without user interaction.
    $client->setAccessType("offline");
    
    // Generate a URL for authorization as it doesn't contain code and error
    if (!isset($_GET['code']) && !isset($_GET['error']))
    {
      // Generate and set state value
      $state = bin2hex(random_bytes(16));
      $client->setState($state);
      $_SESSION['state'] = $state;
    
      // Generate a url that asks permissions.
      $auth_url = $client->createAuthUrl();
      header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
    }
    
    // User authorized the request and authorization code is returned to exchange access and
    // refresh tokens.
    if (isset($_GET['code']))
    {
      // Check the state value
      if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) {
        die('State mismatch. Possible CSRF attack.');
      }
    
      // Get access and refresh tokens (if access_type is offline)
      $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
    
      /** Save access and refresh token to the session variables.
        * ACTION ITEM: In a production app, you likely want to save the
        *              refresh token in a secure persistent storage instead. */
      $_SESSION['access_token'] = $token;
      $_SESSION['refresh_token'] = $client->getRefreshToken();
      
      // Space-separated string of granted scopes if it exists, otherwise null.
      $granted_scopes = $client->getOAuth2Service()->getGrantedScope();
    
      // Determine which scopes user granted and build a dictionary
      $granted_scopes_dict = [
        'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
        'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
      ];
      $_SESSION['granted_scopes_dict'] = $granted_scopes_dict;
      
      $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
      header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }
    
    // An error response e.g. error=access_denied
    if (isset($_GET['error']))
    {
      echo "Error: ". $_GET['error'];
    }
    ?>

    پایتون

    This example uses the Flask framework. It runs a web application at http://localhost:8080 that lets you test the OAuth 2.0 flow. If you go to that URL, you should see five links:

    • Call Drive API: This link points to a page that tries to execute a sample API request if users granted the permission. If necessary, it starts the authorization flow. If successful, the page displays the API response.
    • Mock page to call Calendar API: This link points to a maockpage that tries to execute a sample Calendar API request if users granted the permission. If necessary, it starts the authorization flow. If successful, the page displays the API response.
    • Test the auth flow directly: This link points to a page that tries to send the user through the authorization flow . The app requests permission to submit authorized API requests on the user's behalf.
    • Revoke current credentials: This link points to a page that revokes permissions that the user has already granted to the application.
    • Clear Flask session credentials: This link clears authorization credentials that are stored in the Flask session. This lets you see what would happen if a user who had already granted permission to your app tried to execute an API request in a new session. It also lets you see the API response your app would get if a user had revoked permissions granted to your app, and your app still tried to authorize a request with a revoked access token.
    # -*- coding: utf-8 -*-
    
    import os
    import flask
    import requests
    
    import google.oauth2.credentials
    import google_auth_oauthlib.flow
    import googleapiclient.discovery
    
    # This variable specifies the name of a file that contains the OAuth 2.0
    # information for this application, including its client_id and client_secret.
    CLIENT_SECRETS_FILE = "client_secret.json"
    
    # The OAuth 2.0 access scope allows for access to the
    # authenticated user's account and requires requests to use an SSL connection.
    SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly',
              'https://www.googleapis.com/auth/calendar.readonly']
    API_SERVICE_NAME = 'drive'
    API_VERSION = 'v2'
    
    app = flask.Flask(__name__)
    # Note: A secret key is included in the sample so that it works.
    # If you use this code in your application, replace this with a truly secret
    # key. See https://flask.palletsprojects.com/quickstart/#sessions.
    app.secret_key = 'REPLACE ME - this value is here as a placeholder.'
    
    @app.route('/')
    def index():
      return print_index_table()
    
    @app.route('/drive')
    def drive_api_request():
      if 'credentials' not in flask.session:
        return flask.redirect('authorize')
    
      features = flask.session['features']
    
      if features['drive']:
        # Load credentials from the session.
        credentials = google.oauth2.credentials.Credentials(
            **flask.session['credentials'])
    
        drive = googleapiclient.discovery.build(
            API_SERVICE_NAME, API_VERSION, credentials=credentials)
    
        files = drive.files().list().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(**files)
      else:
        # User didn't authorize read-only Drive activity permission.
        # Update UX and application accordingly
        return '<p>Drive feature is not enabled.</p>'
    
    @app.route('/calendar')
        def calendar_api_request():
          if 'credentials' not in flask.session:
            return flask.redirect('authorize')
    
          features = flask.session['features']
    
          if features['calendar']:
            # User authorized Calendar read permission.
            # Calling the APIs, etc.
            return ('<p>User granted the Google Calendar read permission. '+
                    'This sample code does not include code to call Calendar</p>')
          else:
            # User didn't authorize Calendar read permission.
            # Update UX and application accordingly
            return '<p>Calendar feature is not enabled.</p>'
    
    @app.route('/authorize')
    def authorize():
      # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
      flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
          CLIENT_SECRETS_FILE, scopes=SCOPES)
    
      # The URI created here must exactly match one of the authorized redirect URIs
      # for the OAuth 2.0 client, which you configured in the API Console. If this
      # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
      # error.
      flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
    
      authorization_url, state = flow.authorization_url(
          # Enable offline access so that you can refresh an access token without
          # re-prompting the user for permission. Recommended for web server apps.
          access_type='offline',
          # Enable incremental authorization. Recommended as a best practice.
          include_granted_scopes='true')
    
      # Store the state so the callback can verify the auth server response.
      flask.session['state'] = state
    
      return flask.redirect(authorization_url)
    
    @app.route('/oauth2callback')
    def oauth2callback():
      # Specify the state when creating the flow in the callback so that it can
      # verified in the authorization server response.
      state = flask.session['state']
    
      flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
          CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
      flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
    
      # Use the authorization server's response to fetch the OAuth 2.0 tokens.
      authorization_response = flask.request.url
      flow.fetch_token(authorization_response=authorization_response)
    
      # Store credentials in the session.
      # ACTION ITEM: In a production app, you likely want to save these
      #              credentials in a persistent database instead.
      credentials = flow.credentials
      
      credentials = credentials_to_dict(credentials)
      flask.session['credentials'] = credentials
    
      # Check which scopes user granted
      features = check_granted_scopes(credentials)
      flask.session['features'] = features
      return flask.redirect('/')
      
    
    @app.route('/revoke')
    def revoke():
      if 'credentials' not in flask.session:
        return ('You need to <a href="/authorize">authorize</a> before ' +
                'testing the code to revoke credentials.')
    
      credentials = google.oauth2.credentials.Credentials(
        **flask.session['credentials'])
    
      revoke = requests.post('https://oauth2.googleapis.com/revoke',
          params={'token': credentials.token},
          headers = {'content-type': 'application/x-www-form-urlencoded'})
    
      status_code = getattr(revoke, 'status_code')
      if status_code == 200:
        return('Credentials successfully revoked.' + print_index_table())
      else:
        return('An error occurred.' + print_index_table())
    
    @app.route('/clear')
    def clear_credentials():
      if 'credentials' in flask.session:
        del flask.session['credentials']
      return ('Credentials have been cleared.<br><br>' +
              print_index_table())
    
    def credentials_to_dict(credentials):
      return {'token': credentials.token,
              'refresh_token': credentials.refresh_token,
              'token_uri': credentials.token_uri,
              'client_id': credentials.client_id,
              'client_secret': credentials.client_secret,
              'granted_scopes': credentials.granted_scopes}
    
    def check_granted_scopes(credentials):
      features = {}
      if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']:
        features['drive'] = True
      else:
        features['drive'] = False
    
      if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']:
        features['calendar'] = True
      else:
        features['calendar'] = False
    
      return features
    
    def print_index_table():
      return ('<table>' +
              '<tr><td><a href="/test">Test an API request</a></td>' +
              '<td>Submit an API request and see a formatted JSON response. ' +
              '    Go through the authorization flow if there are no stored ' +
              '    credentials for the user.</td></tr>' +
              '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
              '<td>Go directly to the authorization flow. If there are stored ' +
              '    credentials, you still might not be prompted to reauthorize ' +
              '    the application.</td></tr>' +
              '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
              '<td>Revoke the access token associated with the current user ' +
              '    session. After revoking credentials, if you go to the test ' +
              '    page, you should see an <code>invalid_grant</code> error.' +
              '</td></tr>' +
              '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
              '<td>Clear the access token currently stored in the user session. ' +
              '    After clearing the token, if you <a href="/test">test the ' +
              '    API request</a> again, you should go back to the auth flow.' +
              '</td></tr></table>')
    
    if __name__ == '__main__':
      # When running locally, disable OAuthlib's HTTPs verification.
      # ACTION ITEM for developers:
      #     When running in production *do not* leave this option enabled.
      os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
    
      # This disables the requested scopes and granted scopes check.
      # If users only grant partial request, the warning would not be thrown.
      os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'
    
      # Specify a hostname and port that are set as a valid redirect URI
      # for your API project in the .
      app.run('localhost', 8080, debug=True)

    روبی

    This example uses the Sinatra framework.

    require 'googleauth'
    require 'googleauth/web_user_authorizer'
    require 'googleauth/stores/redis_token_store'
    
    require 'google/apis/drive_v3'
    require 'google/apis/calendar_v3'
    
    require 'sinatra'
    
    configure do
      enable :sessions
    
      # Required, call the from_file method to retrieve the client ID from a
      # client_secret.json file.
      set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')
    
      # Required, scope value
      # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
      scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
               'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']
    
      # Required, Authorizers require a storage instance to manage long term persistence of
      # access and refresh tokens.
      set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
    
      # Required, indicate where the API server will redirect the user after the user completes
      # the authorization flow. The redirect URI is required. The value must exactly
      # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
      # configured in the API Console. If this value doesn't match an authorized URI,
      # you will get a 'redirect_uri_mismatch' error.
      set :callback_uri, '/oauth2callback'
    
      # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
      # from the client_secret.json file. To get these credentials for your application, visit
      # https://console.cloud.google.com/apis/credentials.
      set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope,
                              settings.token_store, callback_uri: settings.callback_uri)
    end
    
    get '/' do
      # NOTE: Assumes the user is already authenticated to the app
      user_id = request.session['user_id']
    
      # Fetch stored credentials for the user from the given request session.
      # nil if none present
      credentials = settings.authorizer.get_credentials(user_id, request)
    
      if credentials.nil?
        # Generate a url that asks the user to authorize requested scope(s).
        # Then, redirect user to the url.
        redirect settings.authorizer.get_authorization_url(request: request)
      end
      
      # User authorized the request. Now, check which scopes were granted.
      if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)
        # User authorized read-only Drive activity permission.
        # Example of using Google Drive API to list filenames in user's Drive.
        drive = Google::Apis::DriveV3::DriveService.new
        files = drive.list_files(options: { authorization: credentials })
        "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
      else
        # User didn't authorize read-only Drive activity permission.
        # Update UX and application accordingly
      end
    
      # Check if user authorized Calendar read permission.
      if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)
        # User authorized Calendar read permission.
        # Calling the APIs, etc.
      else
        # User didn't authorize Calendar read permission.
        # Update UX and application accordingly
      end
    end
    
    # Receive the callback from Google's OAuth 2.0 server.
    get '/oauth2callback' do
      # Handle the result of the oauth callback. Defers the exchange of the code by
      # temporarily stashing the results in the user's session.
      target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
      redirect target_url
    end

    Node.js

    To run this example:

    1. در , add the URL of the local machine to the list of redirect URLs. For example, add http://localhost .
    2. Make sure you have maintenance LTS, active LTS, or current release of Node.js installed.
    3. Create a new directory and change to it. به عنوان مثال:
      mkdir ~/nodejs-oauth2-example
      cd ~/nodejs-oauth2-example
    4. Install the Google API Client Library for Node.js using npm :
      npm install googleapis
    5. Create the files main.js with the following content.
    6. Run the example:
      node .\main.js

    main.js

    const http = require('http');
    const https = require('https');
    const url = require('url');
    const { google } = require('googleapis');
    const crypto = require('crypto');
    const express = require('express');
    const session = require('express-session');
    
    /**
     * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
     * To get these credentials for your application, visit
     * https://console.cloud.google.com/apis/credentials.
     */
    const oauth2Client = new google.auth.OAuth2(
      YOUR_CLIENT_ID,
      YOUR_CLIENT_SECRET,
      YOUR_REDIRECT_URL
    );
    
    // Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    const scopes = [
      'https://www.googleapis.com/auth/drive.metadata.readonly',
      'https://www.googleapis.com/auth/calendar.readonly'
    ];
    
    /* Global variable that stores user credential in this code example.
     * ACTION ITEM for developers:
     *   Store user's refresh token in your data store if
     *   incorporating this code into your real app.
     *   For more information on handling refresh tokens,
     *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
     */
    let userCredential = null;
    
    async function main() {
      const app = express();
    
      app.use(session({
        secret: 'your_secure_secret_key', // Replace with a strong secret
        resave: false,
        saveUninitialized: false,
      }));
    
      // Example on redirecting user to Google's OAuth 2.0 server.
      app.get('/', async (req, res) => {
        // Generate a secure random state value.
        const state = crypto.randomBytes(32).toString('hex');
        // Store state in the session
        req.session.state = state;
    
        // Generate a url that asks permissions for the Drive activity and Google Calendar scope
        const authorizationUrl = oauth2Client.generateAuthUrl({
          // 'online' (default) or 'offline' (gets refresh_token)
          access_type: 'offline',
          /** Pass in the scopes array defined above.
            * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
          scope: scopes,
          // Enable incremental authorization. Recommended as a best practice.
          include_granted_scopes: true,
          // Include the state parameter to reduce the risk of CSRF attacks.
          state: state
        });
    
        res.redirect(authorizationUrl);
      });
    
      // Receive the callback from Google's OAuth 2.0 server.
      app.get('/oauth2callback', async (req, res) => {
        // Handle the OAuth 2.0 server response
        let q = url.parse(req.url, true).query;
    
        if (q.error) { // An error response e.g. error=access_denied
          console.log('Error:' + q.error);
        } else if (q.state !== req.session.state) { //check state value
          console.log('State mismatch. Possible CSRF attack');
          res.end('State mismatch. Possible CSRF attack');
        } else { // Get access and refresh tokens (if access_type is offline)
          let { tokens } = await oauth2Client.getToken(q.code);
          oauth2Client.setCredentials(tokens);
    
          /** Save credential to the global variable in case access token was refreshed.
            * ACTION ITEM: In a production app, you likely want to save the refresh token
            *              in a secure persistent database instead. */
          userCredential = tokens;
          
          // User authorized the request. Now, check which scopes were granted.
          if (tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly'))
          {
            // User authorized read-only Drive activity permission.
            // Example of using Google Drive API to list filenames in user's Drive.
            const drive = google.drive('v3');
            drive.files.list({
              auth: oauth2Client,
              pageSize: 10,
              fields: 'nextPageToken, files(id, name)',
            }, (err1, res1) => {
              if (err1) return console.log('The API returned an error: ' + err1);
              const files = res1.data.files;
              if (files.length) {
                console.log('Files:');
                files.map((file) => {
                  console.log(`${file.name} (${file.id})`);
                });
              } else {
                console.log('No files found.');
              }
            });
          }
          else
          {
            // User didn't authorize read-only Drive activity permission.
            // Update UX and application accordingly
          }
    
          // Check if user authorized Calendar read permission.
          if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
          {
            // User authorized Calendar read permission.
            // Calling the APIs, etc.
          }
          else
          {
            // User didn't authorize Calendar read permission.
            // Update UX and application accordingly
          }
        }
      });
    
      // Example on revoking a token
      app.get('/revoke', async (req, res) => {
        // Build the string for the POST request
        let postData = "token=" + userCredential.access_token;
    
        // Options for POST request to Google's OAuth 2.0 server to revoke a token
        let postOptions = {
          host: 'oauth2.googleapis.com',
          port: '443',
          path: '/revoke',
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': Buffer.byteLength(postData)
          }
        };
    
        // Set up the request
        const postReq = https.request(postOptions, function (res) {
          res.setEncoding('utf8');
          res.on('data', d => {
            console.log('Response: ' + d);
          });
        });
    
        postReq.on('error', error => {
          console.log(error)
        });
    
        // Post the request with data
        postReq.write(postData);
        postReq.end();
      });
    
    
      const server = http.createServer(app);
      server.listen(8080);
    }
    main().catch(console.error);

    HTTP/REST

    This Python example uses the Flask framework and the Requests library to demonstrate the OAuth 2.0 web flow. We recommend using the Google API Client Library for Python for this flow. (The example in the Python tab does use the client library.)

    import json
    import flask
    import requests
    
    app = flask.Flask(__name__)
    
    # To get these credentials (CLIENT_ID CLIENT_SECRET) and for your application, visit
    # https://console.cloud.google.com/apis/credentials.
    CLIENT_ID = '123456789.apps.googleusercontent.com'
    CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app
    
    # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly'
    
    # Indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required. The value must exactly
    # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
    # configured in the API Console. If this value doesn't match an authorized URI,
    # you will get a 'redirect_uri_mismatch' error.
    REDIRECT_URI = 'http://example.com/oauth2callback'
    
    @app.route('/')
    def index():
      if 'credentials' not in flask.session:
        return flask.redirect(flask.url_for('oauth2callback'))
    
      credentials = json.loads(flask.session['credentials'])
    
      if credentials['expires_in'] <= 0:
        return flask.redirect(flask.url_for('oauth2callback'))
      else: 
        # User authorized the request. Now, check which scopes were granted.
        if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['scope']:
          # User authorized read-only Drive activity permission.
          # Example of using Google Drive API to list filenames in user's Drive.
          headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
          req_uri = 'https://www.googleapis.com/drive/v2/files'
          r = requests.get(req_uri, headers=headers).text
        else:
          # User didn't authorize read-only Drive activity permission.
          # Update UX and application accordingly
          r = 'User did not authorize Drive permission.'
    
        # Check if user authorized Calendar read permission.
        if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['scope']:
          # User authorized Calendar read permission.
          # Calling the APIs, etc.
          r += 'User authorized Calendar permission.'
        else:
          # User didn't authorize Calendar read permission.
          # Update UX and application accordingly
          r += 'User did not authorize Calendar permission.'
    
      return r
    
    @app.route('/oauth2callback')
    def oauth2callback():
      if 'code' not in flask.request.args:
        state = str(uuid.uuid4())
        flask.session['state'] = state
        # Generate a url that asks permissions for the Drive activity
        # and Google Calendar scope. Then, redirect user to the url.
        auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                    '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI,
                                                                              SCOPE, state)
        return flask.redirect(auth_uri)
      else:
        if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']:
          return 'State mismatch. Possible CSRF attack.', 400
    
        auth_code = flask.request.args.get('code')
        data = {'code': auth_code,
                'client_id': CLIENT_ID,
                'client_secret': CLIENT_SECRET,
                'redirect_uri': REDIRECT_URI,
                'grant_type': 'authorization_code'}
    
        # Exchange authorization code for access and refresh tokens (if access_type is offline)
        r = requests.post('https://oauth2.googleapis.com/token', data=data)
        flask.session['credentials'] = r.text
        return flask.redirect(flask.url_for('index'))
    
    if __name__ == '__main__':
      import uuid
      app.secret_key = str(uuid.uuid4())
      app.debug = False
      app.run()

    Redirect URI validation rules

    Google applies the following validation rules to redirect URIs in order to help developers keep their applications secure. Your redirect URIs must adhere to these rules. See RFC 3986 section 3 for the definition of domain, host, path, query, scheme and userinfo, mentioned below.

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

    Redirect URIs must use the HTTPS scheme, not plain HTTP. Localhost URIs (including localhost IP address URIs) are exempt from this rule.

    میزبان

    Hosts cannot be raw IP addresses. Localhost IP addresses are exempted from this rule.

    دامنه
  • Host TLDs ( Top Level Domains ) must belong to the public suffix list .
  • Host domains cannot be “googleusercontent.com” .
  • Redirect URIs cannot contain URL shortener domains (eg goo.gl ) unless the app owns the domain. Furthermore, if an app that owns a shortener domain chooses to redirect to that domain, that redirect URI must either contain “/google-callback/” in its path or end with “/google-callback” .
  • اطلاعات کاربری

    Redirect URIs cannot contain the userinfo subcomponent.

    مسیر

    Redirect URIs cannot contain a path traversal (also called directory backtracking), which is represented by an “/..” or “\..” or their URL encoding.

    پرس و جو

    Redirect URIs cannot contain open redirects .

    قطعه

    Redirect URIs cannot contain the fragment component.

    شخصیت ها Redirect URIs cannot contain certain characters including:
    • Wildcard characters ( '*' )
    • کاراکترهای ASCII غیر قابل چاپ
    • Invalid percent encodings (any percent encoding that does not follow URL-encoding form of a percent sign followed by two hexadecimal digits)
    • Null characters (an encoded NULL character, eg, %00 , %C0%80 )

    مجوز افزایشی

    In the OAuth 2.0 protocol, your app requests authorization to access resources, which are identified by scopes. It is considered a best user-experience practice to request authorization for resources at the time you need them. To enable that practice, Google's authorization server supports incremental authorization. This feature lets you request scopes as they are needed and, if the user grants permission for the new scope, returns an authorization code that may be exchanged for a token containing all scopes the user has granted the project.

    For example, an app that lets people sample music tracks and create mixes might need very few resources at sign-in time, perhaps nothing more than the name of the person signing in. However, saving a completed mix would require access to their Google Drive. Most people would find it natural if they only were asked for access to their Google Drive at the time the app actually needed it.

    In this case, at sign-in time the app might request the openid and profile scopes to perform basic sign-in, and then later request the https://www.googleapis.com/auth/drive.file scope at the time of the first request to save a mix.

    To implement incremental authorization, you complete the normal flow for requesting an access token but make sure that the authorization request includes previously granted scopes. This approach allows your app to avoid having to manage multiple access tokens.

    The following rules apply to an access token obtained from an incremental authorization:

    • The token can be used to access resources corresponding to any of the scopes rolled into the new, combined authorization.
    • When you use the refresh token for the combined authorization to obtain an access token, the access token represents the combined authorization and can be used for any of the scope values included in the response.
    • The combined authorization includes all scopes that the user granted to the API project even if the grants were requested from different clients. For example, if a user granted access to one scope using an application's desktop client and then granted another scope to the same application via a mobile client, the combined authorization would include both scopes.
    • If you revoke a token that represents a combined authorization, access to all of that authorization's scopes on behalf of the associated user are revoked simultaneously.

    The language-specific code samples in Step 1: Set authorization parameters and the sample HTTP/REST redirect URL in Step 2: Redirect to Google's OAuth 2.0 server all use incremental authorization. The code samples below also show the code that you need to add to use incremental authorization.

    PHP

    $client->setIncludeGrantedScopes(true);

    پایتون

    In Python, set the include_granted_scopes keyword argument to true to ensure that an authorization request includes previously granted scopes. It is very possible that include_granted_scopes will not be the only keyword argument that you set, as shown in the example below.

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

    روبی

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

    Node.js

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

    HTTP/REST

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

    Refreshing an access token (offline access)

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

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

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

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

    PHP

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

    $client->setAccessType("offline");

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    پایتون

    In Python, set the access_type keyword argument to offline to ensure that you will be able to refresh the access token without having to re-prompt the user for permission. It is very possible that access_type will not be the only keyword argument that you set, as shown in the example below.

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

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    روبی

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

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

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    Node.js

    If your application needs offline access to a Google API, set the API client's access type to 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
    });

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    Access tokens expire. This library will automatically use a refresh token to obtain a new access token if it is about to expire. یک راه آسان برای اطمینان از اینکه همیشه جدیدترین نشانه‌ها را ذخیره می‌کنید، استفاده از رویداد نشانه‌ها است:

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

    This tokens event only occurs in the first authorization, and you need to have set your access_type to offline when calling the generateAuthUrl method to receive the refresh token. If you have already given your app the requisiste permissions without setting the appropriate constraints for receiving a refresh token, you will need to re-authorize the application to receive a fresh refresh token.

    To set the refresh_token at a later time, you can use the setCredentials method:

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

    Once the client has a refresh token, access tokens will be acquired and refreshed automatically in the next call to the API.

    HTTP/REST

    To refresh an access token, your application sends an HTTPS POST request to Google's authorization server ( https://oauth2.googleapis.com/token ) that includes the following parameters:

    فیلدها
    client_id The client ID obtained from the .
    client_secret The client secret obtained from the .
    grant_type As defined in the OAuth 2.0 specification , this field's value must be set to refresh_token .
    refresh_token The refresh token returned from the authorization code exchange.

    The following snippet shows a sample request:

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

    As long as the user has not revoked the access granted to the application, the token server returns a JSON object that contains a new access token. The following snippet shows a sample response:

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

    Note that there are limits on the number of refresh tokens that will be issued; one limit per client/user combination, and another per user across all clients. You should save refresh tokens in long-term storage and continue to use them as long as they remain valid. If your application requests too many refresh tokens, it may run into these limits, in which case older refresh tokens will stop working.

    Revoking a token

    In some cases a user may wish to revoke access given to an application. A user can revoke access by visiting Account Settings . See the Remove site or app access section of the Third-party sites & apps with access to your account support document for more information.

    It is also possible for an application to programmatically revoke the access given to it. Programmatic revocation is important in instances where a user unsubscribes, removes an application, or the API resources required by an app have significantly changed. In other words, part of the removal process can include an API request to ensure the permissions previously granted to the application are removed.

    PHP

    To programmatically revoke a token, call revokeToken() :

    $client->revokeToken();

    پایتون

    To programmatically revoke a token, make a request to https://oauth2.googleapis.com/revoke that includes the token as a parameter and sets the Content-Type header:

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

    روبی

    To programmatically revoke a token, make an HTTP request to the oauth2.revoke endpoint:

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

    The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the status code of the response is 200 . For error conditions, a status code 400 is returned along with an error code.

    Node.js

    To programmatically revoke a token, make an HTTPS POST request to /revoke endpoint:

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

    The token parameter can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the status code of the response is 200 . For error conditions, a status code 400 is returned along with an error code.

    HTTP/REST

    To programmatically revoke a token, your application makes a request to https://oauth2.googleapis.com/revoke and includes the token as a parameter:

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

    The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the HTTP status code of the response is 200 . For error conditions, an HTTP status code 400 is returned along with an error code.

    Time-based access

    Time-based access allows a user to grant your app access to their data for a limited duration to complete an action. Time-based access is available in select Google products during the consent flow, giving users the option to grant access for a limited period of time. An example is the Data Portability API which enables a one-time transfer of data.

    When a user grants your application time-based access, the refresh token will expire after the specified duration. Note that refresh tokens may be invalidated earlier under specific circumstances; see these cases for details. The refresh_token_expires_in field returned in the authorization code exchange response represents the time remaining until the refresh token expires in such cases.

    Implementing Cross-Account Protection

    An additional step you should take to protect your users' accounts is implementing Cross-Account Protection by utilizing Google's Cross-Account Protection Service. This service lets you subscribe to security event notifications which provide information to your application about major changes to the user account. You can then use the information to take action depending on how you decide to respond to events.

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

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

    ،

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

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

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

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

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

    The language-specific examples on this page use Google API Client Libraries to implement OAuth 2.0 authorization. To run the code samples, you must first install the client library for your language.

    When you use a Google API Client Library to handle your application's OAuth 2.0 flow, the client library performs many actions that the application would otherwise need to handle on its own. For example, it determines when the application can use or refresh stored access tokens as well as when the application must reacquire consent. The client library also generates correct redirect URLs and helps to implement redirect handlers that exchange authorization codes for access tokens.

    Google API Client Libraries for server-side applications are available for the following languages:

    پیش نیازها

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

    Any application that calls Google APIs needs to enable those APIs in the .

    To enable an API for your project:

    1. در .
    2. را lists all available APIs, grouped by product family and popularity. If the API you want to enable isn't visible in the list, use search to find it, or click View All in the product family it belongs to.
    3. Select the API you want to enable, then click the Enable button.

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

    Any application that uses OAuth 2.0 to access Google APIs must have authorization credentials that identify the application to Google's OAuth 2.0 server. The following steps explain how to create credentials for your project. Your applications can then use the credentials to access APIs that you have enabled for that project.

    1. Click Create Client .
    2. Select the Web application application type.
    3. Fill in the form and click Create . Applications that use languages and frameworks like PHP, Java, Python, Ruby, and .NET must specify authorized redirect URIs . The redirect URIs are the endpoints to which the OAuth 2.0 server can send responses. These endpoints must adhere to Google's validation rules .

      For testing, you can specify URIs that refer to the local machine, such as http://localhost:8080 . With that in mind, please note that all of the examples in this document use http://localhost:8080 as the redirect URI.

      We recommend that you design your app's auth endpoints so that your application does not expose authorization codes to other resources on the page.

    After creating your credentials, download the client_secret.json file from the . Securely store the file in a location that only your application can access.

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

    Scopes enable your application to only request access to the resources that it needs while also enabling users to control the amount of access that they grant to your application. Thus, there may be an inverse relationship between the number of scopes requested and the likelihood of obtaining user consent.

    Before you start implementing OAuth 2.0 authorization, we recommend that you identify the scopes that your app will need permission to access.

    We also recommend that your application request access to authorization scopes via an incremental authorization process, in which your application requests access to user data in context. This best practice helps users to more easily understand why your application needs the access it is requesting.

    The OAuth 2.0 API Scopes document contains a full list of scopes that you might use to access Google APIs.

    Language-specific requirements

    To run any of the code samples in this document, you'll need a Google account, access to the Internet, and a web browser. If you are using one of the API client libraries, also see the language-specific requirements below.

    PHP

    To run the PHP code samples in this document, you'll need:

    • PHP 8.0 or greater with the command-line interface (CLI) and JSON extension installed.
    • The Composer dependency management tool.
    • The Google APIs Client Library for PHP:

      composer require google/apiclient:^2.15.0

    See Google APIs Client Library for PHP for more information.

    پایتون

    To run the Python code samples in this document, you'll need:

    • Python 3.7 or greater
    • The pip package management tool.
    • The Google APIs Client Library for Python 2.0 release:
      pip install --upgrade google-api-python-client
    • The google-auth , google-auth-oauthlib , and google-auth-httplib2 for user authorization.
      pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
    • The Flask Python web application framework.
      pip install --upgrade flask
    • The requests HTTP library.
      pip install --upgrade requests

    Review the Google API Python client library release note if you aren't able to upgrade python and associated migration guide.

    روبی

    To run the Ruby code samples in this document, you'll need:

    • Ruby 2.6 or greater
    • The Google Auth Library for Ruby:

      gem install googleauth
    • The client libraries for Drive and Calendar Google APIs:

      gem install google-apis-drive_v3 google-apis-calendar_v3
    • The Sinatra Ruby web application framework.

      gem install sinatra

    Node.js

    To run the Node.js code samples in this document, you'll need:

    • The maintenance LTS, active LTS, or current release of Node.js.
    • The Google APIs Node.js Client:

      npm install googleapis crypto express express-session

    HTTP/REST

    You do not need to install any libraries to be able to directly call the OAuth 2.0 endpoints.

    Obtaining OAuth 2.0 access tokens

    The following steps show how your application interacts with Google's OAuth 2.0 server to obtain a user's consent to perform an API request on the user's behalf. Your application must have that consent before it can execute a Google API request that requires user authorization.

    The list below quickly summarizes these steps:

    1. Your application identifies the permissions it needs.
    2. Your application redirects the user to Google along with the list of requested permissions.
    3. The user decides whether to grant the permissions to your application.
    4. Your application finds out what the user decided.
    5. If the user granted the requested permissions, your application retrieves tokens needed to make API requests on the user's behalf.

    Step 1: Set authorization parameters

    Your first step is to create the authorization request. That request sets parameters that identify your application and define the permissions that the user will be asked to grant to your application.

    • If you use a Google client library for OAuth 2.0 authentication and authorization, you create and configure an object that defines these parameters.
    • If you call the Google OAuth 2.0 endpoint directly, you'll generate a URL and set the parameters on that URL.

    The tabs below define the supported authorization parameters for web server applications. The language-specific examples also show how to use a client library or authorization library to configure an object that sets those parameters.

    PHP

    The following code snippet creates a Google\Client() object, which defines the parameters in the authorization request.

    That object uses information from your client_secret.json file to identify your application. (See creating authorization credentials for more about that file.) The object also identifies the scopes that your application is requesting permission to access and the URL to your application's auth endpoint, which will handle the response from Google's OAuth 2.0 server. Finally, the code sets the optional access_type and include_granted_scopes parameters.

    For example, this code requests read-only, offline access to a user's Google Drive metadata and Calendar events:

    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\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);
    
    // Required, call the setRedirectUri function to specify a valid redirect URI for the
    // provided client_id
    $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
    
    // Recommended, offline access will give you both an access and refresh token so that
    // your app can refresh the access token without user interaction.
    $client->setAccessType('offline');
    
    // Recommended, call the setState function. Using a state value can increase your assurance that
    // an incoming connection is the result of an authentication request.
    $client->setState($sample_passthrough_value);
    
    // Optional, if your application knows which user is trying to authenticate, it can use this
    // parameter to provide a hint to the Google Authentication Server.
    $client->setLoginHint('hint@example.com');
    
    // Optional, call the setPrompt function to set "consent" will prompt the user for consent
    $client->setPrompt('consent');
    
    // Optional, call the setIncludeGrantedScopes function with true to enable incremental
    // authorization
    $client->setIncludeGrantedScopes(true);

    پایتون

    The following code snippet uses the google-auth-oauthlib.flow module to construct the authorization request.

    The code constructs a Flow object, which identifies your application using information from the client_secret.json file that you downloaded after creating authorization credentials . That object also identifies the scopes that your application is requesting permission to access and the URL to your application's auth endpoint, which will handle the response from Google's OAuth 2.0 server. Finally, the code sets the optional access_type and include_granted_scopes parameters.

    For example, this code requests read-only, offline access to a user's Google Drive metadata and Calendar events:

    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/drive.metadata.readonly',
                'https://www.googleapis.com/auth/calendar.readonly'])
    
    # Required, indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required. The value must exactly
    # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
    # configured in the API Console. If this value doesn't match an authorized URI,
    # you will get a 'redirect_uri_mismatch' error.
    flow.redirect_uri = 'https://www.example.com/oauth2callback'
    
    # Generate URL for request to Google's OAuth 2.0 server.
    # Use kwargs to set optional request parameters.
    authorization_url, state = flow.authorization_url(
        # Recommended, enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Optional, enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true',
        # Optional, if your application knows which user is trying to authenticate, it can use this
        # parameter to provide a hint to the Google Authentication Server.
        login_hint='hint@example.com',
        # Optional, set prompt to 'consent' will prompt the user for consent
        prompt='consent')

    روبی

    Use the client_secrets.json file that you created to configure a client object in your application. When you configure a client object, you specify the scopes your application needs to access, along with the URL to your application's auth endpoint, which will handle the response from the OAuth 2.0 server.

    For example, this code requests read-only, offline access to a user's Google Drive metadata and Calendar events:

    require 'googleauth'
    require 'googleauth/web_user_authorizer'
    require 'googleauth/stores/redis_token_store'
    
    require 'google/apis/drive_v3'
    require 'google/apis/calendar_v3'
    
    # Required, call the from_file method to retrieve the client ID from a
    # client_secret.json file.
    client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')
    
    # Required, scope value 
    # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
             'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']
    
    # Required, Authorizers require a storage instance to manage long term persistence of
    # access and refresh tokens.
    token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
    
    # Required, indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required. The value must exactly
    # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
    # configured in the API Console. If this value doesn't match an authorized URI,
    # you will get a 'redirect_uri_mismatch' error.
    callback_uri = '/oauth2callback'
    
    # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
    # from the client_secret.json file. To get these credentials for your application, visit
    # https://console.cloud.google.com/apis/credentials.
    authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope,
                                                    token_store, callback_uri)

    Your application uses the client object to perform OAuth 2.0 operations, such as generating authorization request URLs and applying access tokens to HTTP requests.

    Node.js

    The following code snippet creates a google.auth.OAuth2 object, which defines the parameters in the authorization request.

    That object uses information from your client_secret.json file to identify your application. To ask for permissions from a user to retrieve an access token, you redirect them to a consent page. To create a consent page URL:

    const {google} = require('googleapis');
    const crypto = require('crypto');
    const express = require('express');
    const session = require('express-session');
    
    /**
     * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
     * from the client_secret.json file. To get these credentials for your application, visit
     * https://console.cloud.google.com/apis/credentials.
     */
    const oauth2Client = new google.auth.OAuth2(
      YOUR_CLIENT_ID,
      YOUR_CLIENT_SECRET,
      YOUR_REDIRECT_URL
    );
    
    // Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    const scopes = [
      'https://www.googleapis.com/auth/drive.metadata.readonly',
      'https://www.googleapis.com/auth/calendar.readonly'
    ];
    
    // Generate a secure random state value.
    const state = crypto.randomBytes(32).toString('hex');
    
    // Store state in the session
    req.session.state = state;
    
    // Generate a url that asks permissions for the Drive activity and Google Calendar scope
    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true,
      // Include the state parameter to reduce the risk of CSRF attacks.
      state: state
    });

    Important Note - The refresh_token is only returned on the first authorization. جزئیات بیشتر در اینجا .

    HTTP/REST

    Google's OAuth 2.0 endpoint is at https://accounts.google.com/o/oauth2/v2/auth . This endpoint is accessible only over HTTPS. Plain HTTP connections are refused.

    The Google authorization server supports the following query string parameters for web server applications:

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

    The client ID for your application. You can find this value in the .

    redirect_uri مورد نیاز

    تعیین می کند که سرور API کاربر را پس از تکمیل جریان مجوز توسط کاربر به کجا هدایت می کند. The value must exactly match one of the authorized redirect URIs for the OAuth 2.0 client, which you configured in your client's . If this value doesn't match an authorized redirect URI for the provided client_id you will get a redirect_uri_mismatch error.

    Note that the http or https scheme, case, and trailing slash (' / ') must all match.

    response_type مورد نیاز

    Determines whether the Google OAuth 2.0 endpoint returns an authorization code.

    Set the parameter value to code for web server applications.

    scope مورد نیاز

    A space-delimited list of scopes that identify the resources that your application could access on the user's behalf. These values inform the consent screen that Google displays to the user.

    Scopes enable your application to only request access to the resources that it needs while also enabling users to control the amount of access that they grant to your application. Thus, there is an inverse relationship between the number of scopes requested and the likelihood of obtaining user consent.

    We recommend that your application request access to authorization scopes in context whenever possible. By requesting access to user data in context, via incremental authorization , you help users to more easily understand why your application needs the access it is requesting.

    access_type توصیه می شود

    Indicates whether your application can refresh access tokens when the user is not present at the browser. Valid parameter values are online , which is the default value, and offline .

    Set the value to offline if your application needs to refresh access tokens when the user is not present at the browser. This is the method of refreshing access tokens described later in this document. This value instructs the Google authorization server to return a refresh token and an access token the first time that your application exchanges an authorization code for tokens.

    state توصیه می شود

    Specifies any string value that your application uses to maintain state between your authorization request and the authorization server's response. The server returns the exact value that you send as a name=value pair in the URL query component ( ? ) of the redirect_uri after the user consents to or denies your application's access request.

    You can use this parameter for several purposes, such as directing the user to the correct resource in your application, sending nonces, and mitigating cross-site request forgery. Since your redirect_uri can be guessed, using a state value can increase your assurance that an incoming connection is the result of an authentication request. If you generate a random string or encode the hash of a cookie or another value that captures the client's state, you can validate the response to additionally ensure that the request and response originated in the same browser, providing protection against attacks such as cross-site request forgery . See the OpenID Connect documentation for an example of how to create and confirm a state token.

    include_granted_scopes اختیاری

    Enables applications to use incremental authorization to request access to additional scopes in context. If you set this parameter's value to true and the authorization request is granted, then the new access token will also cover any scopes to which the user previously granted the application access. See the incremental authorization section for examples.

    login_hint اختیاری

    If your application knows which user is trying to authenticate, it can use this parameter to provide a hint to the Google Authentication Server. The server uses the hint to simplify the login flow either by prefilling the email field in the sign-in form or by selecting the appropriate multi-login session.

    Set the parameter value to an email address or sub identifier, which is equivalent to the user's Google ID.

    prompt اختیاری

    A space-delimited, case-sensitive list of prompts to present the user. If you don't specify this parameter, the user will be prompted only the first time your project requests access. See Prompting re-consent for more information.

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

    none Do not display any authentication or consent screens. Must not be specified with other values.
    consent Prompt the user for consent.
    select_account Prompt the user to select an account.

    Step 2: Redirect to Google's OAuth 2.0 server

    Redirect the user to Google's OAuth 2.0 server to initiate the authentication and authorization process. Typically, this occurs when your application first needs to access the user's data. In the case of incremental authorization , this step also occurs when your application first needs to access additional resources that it does not yet have permission to access.

    PHP

    1. Generate a URL to request access from Google's OAuth 2.0 server:
      $auth_url = $client->createAuthUrl();
    2. Redirect the user to $auth_url :
      header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

    پایتون

    This example shows how to redirect the user to the authorization URL using the Flask web application framework:

    return flask.redirect(authorization_url)

    روبی

    1. Generate a URL to request access from Google's OAuth 2.0 server:
      auth_uri = authorizer.get_authorization_url(request: request)
    2. Redirect the user to auth_uri .

    Node.js

    1. Use the generated URL authorizationUrl from Step 1 generateAuthUrl method to request access from Google's OAuth 2.0 server.
    2. Redirect the user to authorizationUrl .
      res.redirect(authorizationUrl);

    HTTP/REST

    Sample redirect to Google's authorization server

    An example URL is shown below, with line breaks and spaces for readability.

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

    After you create the request URL, redirect the user to it.

    Google's OAuth 2.0 server authenticates the user and obtains consent from the user for your application to access the requested scopes. The response is sent back to your application using the redirect URL you specified.

    Step 3: Google prompts user for consent

    In this step, the user decides whether to grant your application the requested access. At this stage, Google displays a consent window that shows the name of your application and the Google API services that it is requesting permission to access with the user's authorization credentials and a summary of the scopes of access to be granted. The user can then consent to grant access to one or more scopes requested by your application or refuse the request.

    Your application doesn't need to do anything at this stage as it waits for the response from Google's OAuth 2.0 server indicating whether any access was granted. That response is explained in the following step.

    خطاها

    Requests to Google's OAuth 2.0 authorization endpoint may display user-facing error messages instead of the expected authentication and authorization flows. کدهای خطای رایج و راهکارهای پیشنهادی در زیر فهرست شده‌اند.

    admin_policy_enforced

    The Google Account is unable to authorize one or more scopes requested due to the policies of their Google Workspace administrator. See the Google Workspace Admin help article Control which third-party & internal apps access Google Workspace data for more information about how an administrator may restrict access to all scopes or sensitive and restricted scopes until access is explicitly granted to your OAuth client ID.

    disallowed_useragent

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

    اندروید

    Android developers may encounter this error message when opening authorization requests in android.webkit.WebView . توسعه‌دهندگان باید در عوض از کتابخانه‌های Android مانند Google Sign-In برای Android یا OpenID Foundation's AppAuth برای Android استفاده کنند.

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

    iOS

    iOS and macOS developers may encounter this error when opening authorization requests in WKWebView . Developers should instead use iOS libraries such as Google Sign-In for iOS or OpenID Foundation's AppAuth for iOS .

    Web developers may encounter this error when an iOS or macOS app opens a general web link in an embedded user-agent and a user navigates to Google's OAuth 2.0 authorization endpoint from your site. Developers should allow general links to open in the default link handler of the operating system, which includes both Universal Links handlers or the default browser app. The SFSafariViewController library is also a supported option.

    org_internal

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

    invalid_client

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

    invalid_grant

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

    redirect_uri_mismatch

    The redirect_uri passed in the authorization request does not match an authorized redirect URI for the OAuth client ID. Review authorized redirect URIs in the .

    The redirect_uri parameter may refer to the OAuth out-of-band (OOB) flow that has been deprecated and is no longer supported. برای به روز رسانی ادغام خود به راهنمای مهاجرت مراجعه کنید.

    invalid_request

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

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

    Step 4: Handle the OAuth 2.0 server response

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

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

    یک پاسخ خطا:

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

    پاسخ کد مجوز:

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

    Sample OAuth 2.0 server response

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

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

    After completing the OAuth 2.0 flow, you should be redirected to http://localhost/oauth2callback , which will likely yield a 404 NOT FOUND error unless your local machine serves a file at that address. مرحله بعدی جزئیات بیشتری را در مورد اطلاعات بازگردانده شده در URI هنگامی که کاربر به برنامه شما هدایت می شود ارائه می دهد.

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

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

    PHP

    To exchange an authorization code for an access token, use the fetchAccessTokenWithAuthCode method:

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

    پایتون

    On your callback page, use the google-auth library to verify the authorization server response. Then, use the flow.fetch_token method to exchange the authorization code in that response for an access token:

    state = flask.session['state']
    flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
        'client_secret.json',
        scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'],
        state=state)
    flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
    
    authorization_response = flask.request.url
    flow.fetch_token(authorization_response=authorization_response)
    
    # Store the credentials in the session.
    # ACTION ITEM for developers:
    #     Store user's access and refresh tokens in your data store if
    #     incorporating this code into your real app.
    credentials = flow.credentials
    flask.session['credentials'] = {
        'token': credentials.token,
        'refresh_token': credentials.refresh_token,
        'token_uri': credentials.token_uri,
        'client_id': credentials.client_id,
        'client_secret': credentials.client_secret,
        'granted_scopes': credentials.granted_scopes}

    روبی

    On your callback page, use the googleauth library to verify the authorization server response. Use the authorizer.handle_auth_callback_deferred method to save the authorization code and redirect back to the URL that originally requested authorization. This 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

    Node.js

    To exchange an authorization code for an access token, use the getToken method:

    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

    To exchange an authorization code for an access token, call the https://oauth2.googleapis.com/token endpoint and set the following parameters:

    فیلدها
    client_id The client ID obtained from the .
    client_secret The client secret obtained from the .
    code The authorization code returned from the initial request.
    grant_type As defined in the OAuth 2.0 specification , this field's value must be set to authorization_code .
    redirect_uri One of the redirect URIs listed for your project in the for the given client_id .

    The following snippet shows a sample request:

    POST /token HTTP/1.1
    Host: oauth2.googleapis.com
    Content-Type: application/x-www-form-urlencoded
    
    code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
    client_id=your_client_id&
    client_secret=your_client_secret&
    redirect_uri=https%3A//oauth2.example.com/code&
    grant_type=authorization_code

    Google responds to this request by returning a JSON object that contains a short-lived access token and a refresh token. Note that the refresh token is only returned if your application set the access_type parameter to offline in the initial request to Google's authorization server .

    The response contains the following fields:

    فیلدها
    access_token The token that your application sends to authorize a Google API request.
    expires_in The remaining lifetime of the access token in seconds.
    refresh_token A token that you can use to obtain a new access token. Refresh tokens are valid until the user revokes access or the refresh token expires. Again, this field is only present in this response if you set the access_type parameter to offline in the initial request to Google's authorization server.
    refresh_token_expires_in The remaining lifetime of the refresh token in seconds. This value is only set when the user grants time-based access .
    scope The scopes of access granted by the access_token expressed as a list of space-delimited, case-sensitive strings.
    token_type The type of token returned. At this time, this field's value is always set to Bearer .

    The following snippet shows a sample response:

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

    خطاها

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

    invalid_grant

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

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

    When requesting multiple permissions (scopes), users may not grant your app access to all of them. Your app must verify which scopes were actually granted and gracefully handle situations where some permissions are denied, typically by disabling the features that rely on those denied scopes.

    با این حال، استثناهایی وجود دارد. Google Workspace Enterprise apps with domain-wide delegation of authority , or apps marked as Trusted , bypass the granular permissions consent screen. For these apps, users won't see the granular permission consent screen. Instead, your app will either receive all requested scopes or none.

    For more detailed information, see How to handle granular permissions .

    PHP

    To check which scopes the user has granted, use the getGrantedScope() method:

    // Space-separated string of granted scopes if it exists, otherwise null.
    $granted_scopes = $client->getOAuth2Service()->getGrantedScope();
    
    // Determine which scopes user granted and build a dictionary
    $granted_scopes_dict = [
      'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
      'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
    ];

    پایتون

    The returned credentials object has a granted_scopes property, which is a list of scopes the user has granted to your app.

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

    The following function checks which scopes the user has granted to your app.

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

    روبی

    When requesting multiple scopes at once, check which scopes were granted through the scope property of the credentials object.

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

    Node.js

    When requesting multiple scopes at once, check which scopes were granted through the scope property of the tokens object.

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

    HTTP/REST

    To check whether the user has granted your application access to a particular scope, exam the scope field in the access token response. The scopes of access granted by the access_token expressed as a list of space-delimited, case-sensitive strings.

    For example, the following sample access token response indicates that the user has granted your application access to the read-only Drive activity and Calendar events permissions:

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

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

    PHP

    Use the access token to call Google APIs by completing the following steps:

    1. If you need to apply an access token to a new Google\Client object — for example, if you stored the access token in a user session — use the setAccessToken method:
      $client->setAccessToken($access_token);
    2. Build a service object for the API that you want to call. You build a service object by providing an authorized Google\Client object to the constructor for the API you want to call. For example, to call the Drive API:
      $drive = new Google\Service\Drive($client);
    3. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
      $files = $drive->files->listFiles(array());

    پایتون

    After obtaining an access token, your application can use that token to authorize API requests on behalf of a given user account or service account. Use the user-specific authorization credentials to build a service object for the API that you want to call, and then use that object to make authorized API requests.

    1. Build a service object for the API that you want to call. You build a service object by calling the googleapiclient.discovery library's build method with the name and version of the API and the user credentials: For example, to call version 3 of the Drive API:
      from googleapiclient.discovery import build
      
      drive = build('drive', 'v2', credentials=credentials)
    2. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
      files = drive.files().list().execute()

    روبی

    After obtaining an access token, your application can use that token to make API requests on behalf of a given user account or service account. Use the user-specific authorization credentials to build a service object for the API that you want to call, and then use that object to make authorized API requests.

    1. Build a service object for the API that you want to call. For example, to call version 3 of the Drive API:
      drive = Google::Apis::DriveV3::DriveService.new
    2. Set the credentials on the service:
      drive.authorization = credentials
    3. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
      files = drive.list_files

    Alternately, authorization can be provided on a per-method basis by supplying the options parameter to a method:

    files = drive.list_files(options: { authorization: credentials })

    Node.js

    After obtaining an access token and setting it to the OAuth2 object, use the object to call Google APIs. Your application can use that token to authorize API requests on behalf of a given user account or service account. Build a service object for the API that you want to call. For example, the following code uses the Google Drive API to list filenames in the user's Drive.

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

    HTTP/REST

    After your application obtains an access token, you can use the token to make calls to a Google API on behalf of a given user account if the scope(s) of access required by the API have been granted. To do this, include the access token in a request to the API by including either an access_token query parameter or an Authorization HTTP header Bearer value. When possible, the HTTP header is preferable, because query strings tend to be visible in server logs. In most cases you can use a client library to set up your calls to Google APIs (for example, when calling the Drive Files API ).

    You can try out all the Google APIs and view their scopes at the OAuth 2.0 Playground .

    HTTP GET examples

    A call to the drive.files endpoint (the Drive Files API) using the Authorization: Bearer HTTP header might look like the following. Note that you need to specify your own access token:

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

    Here is a call to the same API for the authenticated user using the access_token query string parameter:

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

    curl examples

    You can test these commands with the curl command-line application. Here's an example that uses the HTTP header option (preferred):

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

    Or, alternatively, the query string parameter option:

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

    مثال کامل

    The following example prints a JSON-formatted list of files in a user's Google Drive after the user authenticates and gives consent for the application to access the user's Drive metadata.

    PHP

    To run this example:

    1. در , add the URL of the local machine to the list of redirect URLs. For example, add http://localhost:8080 .
    2. Create a new directory and change to it. به عنوان مثال:
      mkdir ~/php-oauth2-example
      cd ~/php-oauth2-example
    3. Install the Google API Client Library for PHP using Composer :
      composer require google/apiclient:^2.15.0
    4. Create the files index.php and oauth2callback.php with the following content.
    5. Run the example with the PHP's built-in test web server:
      php -S localhost:8080 ~/php-oauth2-example

    index.php

    <?php
    require_once __DIR__.'/vendor/autoload.php';
    
    session_start();
    
    $client = new Google\Client();
    $client->setAuthConfig('client_secret.json');
    
    // User granted permission as an access token is in the session.
    if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
    {
      $client->setAccessToken($_SESSION['access_token']);
      
      // Check if user granted Drive permission
      if ($_SESSION['granted_scopes_dict']['Drive']) {
        echo "Drive feature is enabled.";
        echo "</br>";
        $drive = new Drive($client);
        $files = array();
        $response = $drive->files->listFiles(array());
        foreach ($response->files as $file) {
            echo "File: " . $file->name . " (" . $file->id . ")";
            echo "</br>";
        }
      } else {
        echo "Drive feature is NOT enabled.";
        echo "</br>";
      }
    
       // Check if user granted Calendar permission
      if ($_SESSION['granted_scopes_dict']['Calendar']) {
        echo "Calendar feature is enabled.";
        echo "</br>";
      } else {
        echo "Calendar feature is NOT enabled.";
        echo "</br>";
      }
    }
    else
    {
      // Redirect users to outh2call.php which redirects users to Google OAuth 2.0
      $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
      header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }
    ?>

    oauth2callback.php

    <?php
    require_once __DIR__.'/vendor/autoload.php';
    
    session_start();
    
    $client = new Google\Client();
    
    // Required, call the setAuthConfig function to load authorization credentials from
    // client_secret.json file.
    $client->setAuthConfigFile('client_secret.json');
    $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF']);
    
    // Required, to set the scope value, call the addScope function.
    $client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);
    
    // Enable incremental authorization. Recommended as a best practice.
    $client->setIncludeGrantedScopes(true);
    
    // Recommended, offline access will give you both an access and refresh token so that
    // your app can refresh the access token without user interaction.
    $client->setAccessType("offline");
    
    // Generate a URL for authorization as it doesn't contain code and error
    if (!isset($_GET['code']) && !isset($_GET['error']))
    {
      // Generate and set state value
      $state = bin2hex(random_bytes(16));
      $client->setState($state);
      $_SESSION['state'] = $state;
    
      // Generate a url that asks permissions.
      $auth_url = $client->createAuthUrl();
      header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
    }
    
    // User authorized the request and authorization code is returned to exchange access and
    // refresh tokens.
    if (isset($_GET['code']))
    {
      // Check the state value
      if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) {
        die('State mismatch. Possible CSRF attack.');
      }
    
      // Get access and refresh tokens (if access_type is offline)
      $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
    
      /** Save access and refresh token to the session variables.
        * ACTION ITEM: In a production app, you likely want to save the
        *              refresh token in a secure persistent storage instead. */
      $_SESSION['access_token'] = $token;
      $_SESSION['refresh_token'] = $client->getRefreshToken();
      
      // Space-separated string of granted scopes if it exists, otherwise null.
      $granted_scopes = $client->getOAuth2Service()->getGrantedScope();
    
      // Determine which scopes user granted and build a dictionary
      $granted_scopes_dict = [
        'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
        'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
      ];
      $_SESSION['granted_scopes_dict'] = $granted_scopes_dict;
      
      $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
      header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }
    
    // An error response e.g. error=access_denied
    if (isset($_GET['error']))
    {
      echo "Error: ". $_GET['error'];
    }
    ?>

    پایتون

    This example uses the Flask framework. It runs a web application at http://localhost:8080 that lets you test the OAuth 2.0 flow. If you go to that URL, you should see five links:

    • Call Drive API: This link points to a page that tries to execute a sample API request if users granted the permission. If necessary, it starts the authorization flow. If successful, the page displays the API response.
    • Mock page to call Calendar API: This link points to a maockpage that tries to execute a sample Calendar API request if users granted the permission. If necessary, it starts the authorization flow. If successful, the page displays the API response.
    • Test the auth flow directly: This link points to a page that tries to send the user through the authorization flow . The app requests permission to submit authorized API requests on the user's behalf.
    • Revoke current credentials: This link points to a page that revokes permissions that the user has already granted to the application.
    • Clear Flask session credentials: This link clears authorization credentials that are stored in the Flask session. This lets you see what would happen if a user who had already granted permission to your app tried to execute an API request in a new session. It also lets you see the API response your app would get if a user had revoked permissions granted to your app, and your app still tried to authorize a request with a revoked access token.
    # -*- coding: utf-8 -*-
    
    import os
    import flask
    import requests
    
    import google.oauth2.credentials
    import google_auth_oauthlib.flow
    import googleapiclient.discovery
    
    # This variable specifies the name of a file that contains the OAuth 2.0
    # information for this application, including its client_id and client_secret.
    CLIENT_SECRETS_FILE = "client_secret.json"
    
    # The OAuth 2.0 access scope allows for access to the
    # authenticated user's account and requires requests to use an SSL connection.
    SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly',
              'https://www.googleapis.com/auth/calendar.readonly']
    API_SERVICE_NAME = 'drive'
    API_VERSION = 'v2'
    
    app = flask.Flask(__name__)
    # Note: A secret key is included in the sample so that it works.
    # If you use this code in your application, replace this with a truly secret
    # key. See https://flask.palletsprojects.com/quickstart/#sessions.
    app.secret_key = 'REPLACE ME - this value is here as a placeholder.'
    
    @app.route('/')
    def index():
      return print_index_table()
    
    @app.route('/drive')
    def drive_api_request():
      if 'credentials' not in flask.session:
        return flask.redirect('authorize')
    
      features = flask.session['features']
    
      if features['drive']:
        # Load credentials from the session.
        credentials = google.oauth2.credentials.Credentials(
            **flask.session['credentials'])
    
        drive = googleapiclient.discovery.build(
            API_SERVICE_NAME, API_VERSION, credentials=credentials)
    
        files = drive.files().list().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(**files)
      else:
        # User didn't authorize read-only Drive activity permission.
        # Update UX and application accordingly
        return '<p>Drive feature is not enabled.</p>'
    
    @app.route('/calendar')
        def calendar_api_request():
          if 'credentials' not in flask.session:
            return flask.redirect('authorize')
    
          features = flask.session['features']
    
          if features['calendar']:
            # User authorized Calendar read permission.
            # Calling the APIs, etc.
            return ('<p>User granted the Google Calendar read permission. '+
                    'This sample code does not include code to call Calendar</p>')
          else:
            # User didn't authorize Calendar read permission.
            # Update UX and application accordingly
            return '<p>Calendar feature is not enabled.</p>'
    
    @app.route('/authorize')
    def authorize():
      # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
      flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
          CLIENT_SECRETS_FILE, scopes=SCOPES)
    
      # The URI created here must exactly match one of the authorized redirect URIs
      # for the OAuth 2.0 client, which you configured in the API Console. If this
      # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
      # error.
      flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
    
      authorization_url, state = flow.authorization_url(
          # Enable offline access so that you can refresh an access token without
          # re-prompting the user for permission. Recommended for web server apps.
          access_type='offline',
          # Enable incremental authorization. Recommended as a best practice.
          include_granted_scopes='true')
    
      # Store the state so the callback can verify the auth server response.
      flask.session['state'] = state
    
      return flask.redirect(authorization_url)
    
    @app.route('/oauth2callback')
    def oauth2callback():
      # Specify the state when creating the flow in the callback so that it can
      # verified in the authorization server response.
      state = flask.session['state']
    
      flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
          CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
      flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
    
      # Use the authorization server's response to fetch the OAuth 2.0 tokens.
      authorization_response = flask.request.url
      flow.fetch_token(authorization_response=authorization_response)
    
      # Store credentials in the session.
      # ACTION ITEM: In a production app, you likely want to save these
      #              credentials in a persistent database instead.
      credentials = flow.credentials
      
      credentials = credentials_to_dict(credentials)
      flask.session['credentials'] = credentials
    
      # Check which scopes user granted
      features = check_granted_scopes(credentials)
      flask.session['features'] = features
      return flask.redirect('/')
      
    
    @app.route('/revoke')
    def revoke():
      if 'credentials' not in flask.session:
        return ('You need to <a href="/authorize">authorize</a> before ' +
                'testing the code to revoke credentials.')
    
      credentials = google.oauth2.credentials.Credentials(
        **flask.session['credentials'])
    
      revoke = requests.post('https://oauth2.googleapis.com/revoke',
          params={'token': credentials.token},
          headers = {'content-type': 'application/x-www-form-urlencoded'})
    
      status_code = getattr(revoke, 'status_code')
      if status_code == 200:
        return('Credentials successfully revoked.' + print_index_table())
      else:
        return('An error occurred.' + print_index_table())
    
    @app.route('/clear')
    def clear_credentials():
      if 'credentials' in flask.session:
        del flask.session['credentials']
      return ('Credentials have been cleared.<br><br>' +
              print_index_table())
    
    def credentials_to_dict(credentials):
      return {'token': credentials.token,
              'refresh_token': credentials.refresh_token,
              'token_uri': credentials.token_uri,
              'client_id': credentials.client_id,
              'client_secret': credentials.client_secret,
              'granted_scopes': credentials.granted_scopes}
    
    def check_granted_scopes(credentials):
      features = {}
      if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']:
        features['drive'] = True
      else:
        features['drive'] = False
    
      if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']:
        features['calendar'] = True
      else:
        features['calendar'] = False
    
      return features
    
    def print_index_table():
      return ('<table>' +
              '<tr><td><a href="/test">Test an API request</a></td>' +
              '<td>Submit an API request and see a formatted JSON response. ' +
              '    Go through the authorization flow if there are no stored ' +
              '    credentials for the user.</td></tr>' +
              '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
              '<td>Go directly to the authorization flow. If there are stored ' +
              '    credentials, you still might not be prompted to reauthorize ' +
              '    the application.</td></tr>' +
              '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
              '<td>Revoke the access token associated with the current user ' +
              '    session. After revoking credentials, if you go to the test ' +
              '    page, you should see an <code>invalid_grant</code> error.' +
              '</td></tr>' +
              '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
              '<td>Clear the access token currently stored in the user session. ' +
              '    After clearing the token, if you <a href="/test">test the ' +
              '    API request</a> again, you should go back to the auth flow.' +
              '</td></tr></table>')
    
    if __name__ == '__main__':
      # When running locally, disable OAuthlib's HTTPs verification.
      # ACTION ITEM for developers:
      #     When running in production *do not* leave this option enabled.
      os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
    
      # This disables the requested scopes and granted scopes check.
      # If users only grant partial request, the warning would not be thrown.
      os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'
    
      # Specify a hostname and port that are set as a valid redirect URI
      # for your API project in the .
      app.run('localhost', 8080, debug=True)

    روبی

    This example uses the Sinatra framework.

    require 'googleauth'
    require 'googleauth/web_user_authorizer'
    require 'googleauth/stores/redis_token_store'
    
    require 'google/apis/drive_v3'
    require 'google/apis/calendar_v3'
    
    require 'sinatra'
    
    configure do
      enable :sessions
    
      # Required, call the from_file method to retrieve the client ID from a
      # client_secret.json file.
      set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')
    
      # Required, scope value
      # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
      scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
               'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']
    
      # Required, Authorizers require a storage instance to manage long term persistence of
      # access and refresh tokens.
      set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
    
      # Required, indicate where the API server will redirect the user after the user completes
      # the authorization flow. The redirect URI is required. The value must exactly
      # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
      # configured in the API Console. If this value doesn't match an authorized URI,
      # you will get a 'redirect_uri_mismatch' error.
      set :callback_uri, '/oauth2callback'
    
      # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
      # from the client_secret.json file. To get these credentials for your application, visit
      # https://console.cloud.google.com/apis/credentials.
      set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope,
                              settings.token_store, callback_uri: settings.callback_uri)
    end
    
    get '/' do
      # NOTE: Assumes the user is already authenticated to the app
      user_id = request.session['user_id']
    
      # Fetch stored credentials for the user from the given request session.
      # nil if none present
      credentials = settings.authorizer.get_credentials(user_id, request)
    
      if credentials.nil?
        # Generate a url that asks the user to authorize requested scope(s).
        # Then, redirect user to the url.
        redirect settings.authorizer.get_authorization_url(request: request)
      end
      
      # User authorized the request. Now, check which scopes were granted.
      if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)
        # User authorized read-only Drive activity permission.
        # Example of using Google Drive API to list filenames in user's Drive.
        drive = Google::Apis::DriveV3::DriveService.new
        files = drive.list_files(options: { authorization: credentials })
        "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
      else
        # User didn't authorize read-only Drive activity permission.
        # Update UX and application accordingly
      end
    
      # Check if user authorized Calendar read permission.
      if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)
        # User authorized Calendar read permission.
        # Calling the APIs, etc.
      else
        # User didn't authorize Calendar read permission.
        # Update UX and application accordingly
      end
    end
    
    # Receive the callback from Google's OAuth 2.0 server.
    get '/oauth2callback' do
      # Handle the result of the oauth callback. Defers the exchange of the code by
      # temporarily stashing the results in the user's session.
      target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
      redirect target_url
    end

    Node.js

    To run this example:

    1. در , add the URL of the local machine to the list of redirect URLs. For example, add http://localhost .
    2. Make sure you have maintenance LTS, active LTS, or current release of Node.js installed.
    3. Create a new directory and change to it. به عنوان مثال:
      mkdir ~/nodejs-oauth2-example
      cd ~/nodejs-oauth2-example
    4. Install the Google API Client Library for Node.js using npm :
      npm install googleapis
    5. Create the files main.js with the following content.
    6. Run the example:
      node .\main.js

    main.js

    const http = require('http');
    const https = require('https');
    const url = require('url');
    const { google } = require('googleapis');
    const crypto = require('crypto');
    const express = require('express');
    const session = require('express-session');
    
    /**
     * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
     * To get these credentials for your application, visit
     * https://console.cloud.google.com/apis/credentials.
     */
    const oauth2Client = new google.auth.OAuth2(
      YOUR_CLIENT_ID,
      YOUR_CLIENT_SECRET,
      YOUR_REDIRECT_URL
    );
    
    // Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    const scopes = [
      'https://www.googleapis.com/auth/drive.metadata.readonly',
      'https://www.googleapis.com/auth/calendar.readonly'
    ];
    
    /* Global variable that stores user credential in this code example.
     * ACTION ITEM for developers:
     *   Store user's refresh token in your data store if
     *   incorporating this code into your real app.
     *   For more information on handling refresh tokens,
     *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
     */
    let userCredential = null;
    
    async function main() {
      const app = express();
    
      app.use(session({
        secret: 'your_secure_secret_key', // Replace with a strong secret
        resave: false,
        saveUninitialized: false,
      }));
    
      // Example on redirecting user to Google's OAuth 2.0 server.
      app.get('/', async (req, res) => {
        // Generate a secure random state value.
        const state = crypto.randomBytes(32).toString('hex');
        // Store state in the session
        req.session.state = state;
    
        // Generate a url that asks permissions for the Drive activity and Google Calendar scope
        const authorizationUrl = oauth2Client.generateAuthUrl({
          // 'online' (default) or 'offline' (gets refresh_token)
          access_type: 'offline',
          /** Pass in the scopes array defined above.
            * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
          scope: scopes,
          // Enable incremental authorization. Recommended as a best practice.
          include_granted_scopes: true,
          // Include the state parameter to reduce the risk of CSRF attacks.
          state: state
        });
    
        res.redirect(authorizationUrl);
      });
    
      // Receive the callback from Google's OAuth 2.0 server.
      app.get('/oauth2callback', async (req, res) => {
        // Handle the OAuth 2.0 server response
        let q = url.parse(req.url, true).query;
    
        if (q.error) { // An error response e.g. error=access_denied
          console.log('Error:' + q.error);
        } else if (q.state !== req.session.state) { //check state value
          console.log('State mismatch. Possible CSRF attack');
          res.end('State mismatch. Possible CSRF attack');
        } else { // Get access and refresh tokens (if access_type is offline)
          let { tokens } = await oauth2Client.getToken(q.code);
          oauth2Client.setCredentials(tokens);
    
          /** Save credential to the global variable in case access token was refreshed.
            * ACTION ITEM: In a production app, you likely want to save the refresh token
            *              in a secure persistent database instead. */
          userCredential = tokens;
          
          // User authorized the request. Now, check which scopes were granted.
          if (tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly'))
          {
            // User authorized read-only Drive activity permission.
            // Example of using Google Drive API to list filenames in user's Drive.
            const drive = google.drive('v3');
            drive.files.list({
              auth: oauth2Client,
              pageSize: 10,
              fields: 'nextPageToken, files(id, name)',
            }, (err1, res1) => {
              if (err1) return console.log('The API returned an error: ' + err1);
              const files = res1.data.files;
              if (files.length) {
                console.log('Files:');
                files.map((file) => {
                  console.log(`${file.name} (${file.id})`);
                });
              } else {
                console.log('No files found.');
              }
            });
          }
          else
          {
            // User didn't authorize read-only Drive activity permission.
            // Update UX and application accordingly
          }
    
          // Check if user authorized Calendar read permission.
          if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
          {
            // User authorized Calendar read permission.
            // Calling the APIs, etc.
          }
          else
          {
            // User didn't authorize Calendar read permission.
            // Update UX and application accordingly
          }
        }
      });
    
      // Example on revoking a token
      app.get('/revoke', async (req, res) => {
        // Build the string for the POST request
        let postData = "token=" + userCredential.access_token;
    
        // Options for POST request to Google's OAuth 2.0 server to revoke a token
        let postOptions = {
          host: 'oauth2.googleapis.com',
          port: '443',
          path: '/revoke',
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': Buffer.byteLength(postData)
          }
        };
    
        // Set up the request
        const postReq = https.request(postOptions, function (res) {
          res.setEncoding('utf8');
          res.on('data', d => {
            console.log('Response: ' + d);
          });
        });
    
        postReq.on('error', error => {
          console.log(error)
        });
    
        // Post the request with data
        postReq.write(postData);
        postReq.end();
      });
    
    
      const server = http.createServer(app);
      server.listen(8080);
    }
    main().catch(console.error);

    HTTP/REST

    This Python example uses the Flask framework and the Requests library to demonstrate the OAuth 2.0 web flow. We recommend using the Google API Client Library for Python for this flow. (The example in the Python tab does use the client library.)

    import json
    import flask
    import requests
    
    app = flask.Flask(__name__)
    
    # To get these credentials (CLIENT_ID CLIENT_SECRET) and for your application, visit
    # https://console.cloud.google.com/apis/credentials.
    CLIENT_ID = '123456789.apps.googleusercontent.com'
    CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app
    
    # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly'
    
    # Indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required. The value must exactly
    # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
    # configured in the API Console. If this value doesn't match an authorized URI,
    # you will get a 'redirect_uri_mismatch' error.
    REDIRECT_URI = 'http://example.com/oauth2callback'
    
    @app.route('/')
    def index():
      if 'credentials' not in flask.session:
        return flask.redirect(flask.url_for('oauth2callback'))
    
      credentials = json.loads(flask.session['credentials'])
    
      if credentials['expires_in'] <= 0:
        return flask.redirect(flask.url_for('oauth2callback'))
      else: 
        # User authorized the request. Now, check which scopes were granted.
        if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['scope']:
          # User authorized read-only Drive activity permission.
          # Example of using Google Drive API to list filenames in user's Drive.
          headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
          req_uri = 'https://www.googleapis.com/drive/v2/files'
          r = requests.get(req_uri, headers=headers).text
        else:
          # User didn't authorize read-only Drive activity permission.
          # Update UX and application accordingly
          r = 'User did not authorize Drive permission.'
    
        # Check if user authorized Calendar read permission.
        if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['scope']:
          # User authorized Calendar read permission.
          # Calling the APIs, etc.
          r += 'User authorized Calendar permission.'
        else:
          # User didn't authorize Calendar read permission.
          # Update UX and application accordingly
          r += 'User did not authorize Calendar permission.'
    
      return r
    
    @app.route('/oauth2callback')
    def oauth2callback():
      if 'code' not in flask.request.args:
        state = str(uuid.uuid4())
        flask.session['state'] = state
        # Generate a url that asks permissions for the Drive activity
        # and Google Calendar scope. Then, redirect user to the url.
        auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                    '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI,
                                                                              SCOPE, state)
        return flask.redirect(auth_uri)
      else:
        if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']:
          return 'State mismatch. Possible CSRF attack.', 400
    
        auth_code = flask.request.args.get('code')
        data = {'code': auth_code,
                'client_id': CLIENT_ID,
                'client_secret': CLIENT_SECRET,
                'redirect_uri': REDIRECT_URI,
                'grant_type': 'authorization_code'}
    
        # Exchange authorization code for access and refresh tokens (if access_type is offline)
        r = requests.post('https://oauth2.googleapis.com/token', data=data)
        flask.session['credentials'] = r.text
        return flask.redirect(flask.url_for('index'))
    
    if __name__ == '__main__':
      import uuid
      app.secret_key = str(uuid.uuid4())
      app.debug = False
      app.run()

    Redirect URI validation rules

    Google applies the following validation rules to redirect URIs in order to help developers keep their applications secure. Your redirect URIs must adhere to these rules. See RFC 3986 section 3 for the definition of domain, host, path, query, scheme and userinfo, mentioned below.

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

    Redirect URIs must use the HTTPS scheme, not plain HTTP. Localhost URIs (including localhost IP address URIs) are exempt from this rule.

    میزبان

    Hosts cannot be raw IP addresses. Localhost IP addresses are exempted from this rule.

    دامنه
  • Host TLDs ( Top Level Domains ) must belong to the public suffix list .
  • Host domains cannot be “googleusercontent.com” .
  • Redirect URIs cannot contain URL shortener domains (eg goo.gl ) unless the app owns the domain. Furthermore, if an app that owns a shortener domain chooses to redirect to that domain, that redirect URI must either contain “/google-callback/” in its path or end with “/google-callback” .
  • اطلاعات کاربری

    Redirect URIs cannot contain the userinfo subcomponent.

    مسیر

    Redirect URIs cannot contain a path traversal (also called directory backtracking), which is represented by an “/..” or “\..” or their URL encoding.

    پرس و جو

    Redirect URIs cannot contain open redirects .

    قطعه

    Redirect URIs cannot contain the fragment component.

    شخصیت ها Redirect URIs cannot contain certain characters including:
    • Wildcard characters ( '*' )
    • کاراکترهای ASCII غیر قابل چاپ
    • Invalid percent encodings (any percent encoding that does not follow URL-encoding form of a percent sign followed by two hexadecimal digits)
    • Null characters (an encoded NULL character, eg, %00 , %C0%80 )

    مجوز افزایشی

    In the OAuth 2.0 protocol, your app requests authorization to access resources, which are identified by scopes. It is considered a best user-experience practice to request authorization for resources at the time you need them. To enable that practice, Google's authorization server supports incremental authorization. This feature lets you request scopes as they are needed and, if the user grants permission for the new scope, returns an authorization code that may be exchanged for a token containing all scopes the user has granted the project.

    For example, an app that lets people sample music tracks and create mixes might need very few resources at sign-in time, perhaps nothing more than the name of the person signing in. However, saving a completed mix would require access to their Google Drive. Most people would find it natural if they only were asked for access to their Google Drive at the time the app actually needed it.

    In this case, at sign-in time the app might request the openid and profile scopes to perform basic sign-in, and then later request the https://www.googleapis.com/auth/drive.file scope at the time of the first request to save a mix.

    To implement incremental authorization, you complete the normal flow for requesting an access token but make sure that the authorization request includes previously granted scopes. This approach allows your app to avoid having to manage multiple access tokens.

    The following rules apply to an access token obtained from an incremental authorization:

    • The token can be used to access resources corresponding to any of the scopes rolled into the new, combined authorization.
    • When you use the refresh token for the combined authorization to obtain an access token, the access token represents the combined authorization and can be used for any of the scope values included in the response.
    • The combined authorization includes all scopes that the user granted to the API project even if the grants were requested from different clients. For example, if a user granted access to one scope using an application's desktop client and then granted another scope to the same application via a mobile client, the combined authorization would include both scopes.
    • If you revoke a token that represents a combined authorization, access to all of that authorization's scopes on behalf of the associated user are revoked simultaneously.

    The language-specific code samples in Step 1: Set authorization parameters and the sample HTTP/REST redirect URL in Step 2: Redirect to Google's OAuth 2.0 server all use incremental authorization. The code samples below also show the code that you need to add to use incremental authorization.

    PHP

    $client->setIncludeGrantedScopes(true);

    پایتون

    In Python, set the include_granted_scopes keyword argument to true to ensure that an authorization request includes previously granted scopes. It is very possible that include_granted_scopes will not be the only keyword argument that you set, as shown in the example below.

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

    روبی

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

    Node.js

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

    HTTP/REST

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

    Refreshing an access token (offline access)

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

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

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

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

    PHP

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

    $client->setAccessType("offline");

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    پایتون

    In Python, set the access_type keyword argument to offline to ensure that you will be able to refresh the access token without having to re-prompt the user for permission. It is very possible that access_type will not be the only keyword argument that you set, as shown in the example below.

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

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    روبی

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

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

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    Node.js

    If your application needs offline access to a Google API, set the API client's access type to 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
    });

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    Access tokens expire. This library will automatically use a refresh token to obtain a new access token if it is about to expire. یک راه آسان برای اطمینان از اینکه همیشه جدیدترین نشانه‌ها را ذخیره می‌کنید، استفاده از رویداد نشانه‌ها است:

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

    This tokens event only occurs in the first authorization, and you need to have set your access_type to offline when calling the generateAuthUrl method to receive the refresh token. If you have already given your app the requisiste permissions without setting the appropriate constraints for receiving a refresh token, you will need to re-authorize the application to receive a fresh refresh token.

    To set the refresh_token at a later time, you can use the setCredentials method:

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

    Once the client has a refresh token, access tokens will be acquired and refreshed automatically in the next call to the API.

    HTTP/REST

    To refresh an access token, your application sends an HTTPS POST request to Google's authorization server ( https://oauth2.googleapis.com/token ) that includes the following parameters:

    فیلدها
    client_id The client ID obtained from the .
    client_secret The client secret obtained from the .
    grant_type As defined in the OAuth 2.0 specification , this field's value must be set to refresh_token .
    refresh_token The refresh token returned from the authorization code exchange.

    The following snippet shows a sample request:

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

    As long as the user has not revoked the access granted to the application, the token server returns a JSON object that contains a new access token. The following snippet shows a sample response:

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

    Note that there are limits on the number of refresh tokens that will be issued; one limit per client/user combination, and another per user across all clients. You should save refresh tokens in long-term storage and continue to use them as long as they remain valid. If your application requests too many refresh tokens, it may run into these limits, in which case older refresh tokens will stop working.

    Revoking a token

    In some cases a user may wish to revoke access given to an application. A user can revoke access by visiting Account Settings . See the Remove site or app access section of the Third-party sites & apps with access to your account support document for more information.

    It is also possible for an application to programmatically revoke the access given to it. Programmatic revocation is important in instances where a user unsubscribes, removes an application, or the API resources required by an app have significantly changed. In other words, part of the removal process can include an API request to ensure the permissions previously granted to the application are removed.

    PHP

    To programmatically revoke a token, call revokeToken() :

    $client->revokeToken();

    پایتون

    To programmatically revoke a token, make a request to https://oauth2.googleapis.com/revoke that includes the token as a parameter and sets the Content-Type header:

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

    روبی

    To programmatically revoke a token, make an HTTP request to the oauth2.revoke endpoint:

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

    The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the status code of the response is 200 . For error conditions, a status code 400 is returned along with an error code.

    Node.js

    To programmatically revoke a token, make an HTTPS POST request to /revoke endpoint:

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

    The token parameter can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the status code of the response is 200 . For error conditions, a status code 400 is returned along with an error code.

    HTTP/REST

    To programmatically revoke a token, your application makes a request to https://oauth2.googleapis.com/revoke and includes the token as a parameter:

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

    The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the HTTP status code of the response is 200 . For error conditions, an HTTP status code 400 is returned along with an error code.

    Time-based access

    Time-based access allows a user to grant your app access to their data for a limited duration to complete an action. Time-based access is available in select Google products during the consent flow, giving users the option to grant access for a limited period of time. An example is the Data Portability API which enables a one-time transfer of data.

    When a user grants your application time-based access, the refresh token will expire after the specified duration. Note that refresh tokens may be invalidated earlier under specific circumstances; see these cases for details. The refresh_token_expires_in field returned in the authorization code exchange response represents the time remaining until the refresh token expires in such cases.

    Implementing Cross-Account Protection

    An additional step you should take to protect your users' accounts is implementing Cross-Account Protection by utilizing Google's Cross-Account Protection Service. This service lets you subscribe to security event notifications which provide information to your application about major changes to the user account. You can then use the information to take action depending on how you decide to respond to events.

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

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

    ،

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

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

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

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

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

    The language-specific examples on this page use Google API Client Libraries to implement OAuth 2.0 authorization. To run the code samples, you must first install the client library for your language.

    When you use a Google API Client Library to handle your application's OAuth 2.0 flow, the client library performs many actions that the application would otherwise need to handle on its own. For example, it determines when the application can use or refresh stored access tokens as well as when the application must reacquire consent. The client library also generates correct redirect URLs and helps to implement redirect handlers that exchange authorization codes for access tokens.

    Google API Client Libraries for server-side applications are available for the following languages:

    پیش نیازها

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

    Any application that calls Google APIs needs to enable those APIs in the .

    To enable an API for your project:

    1. در .
    2. را lists all available APIs, grouped by product family and popularity. If the API you want to enable isn't visible in the list, use search to find it, or click View All in the product family it belongs to.
    3. Select the API you want to enable, then click the Enable button.

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

    Any application that uses OAuth 2.0 to access Google APIs must have authorization credentials that identify the application to Google's OAuth 2.0 server. The following steps explain how to create credentials for your project. Your applications can then use the credentials to access APIs that you have enabled for that project.

    1. Click Create Client .
    2. Select the Web application application type.
    3. Fill in the form and click Create . Applications that use languages and frameworks like PHP, Java, Python, Ruby, and .NET must specify authorized redirect URIs . The redirect URIs are the endpoints to which the OAuth 2.0 server can send responses. These endpoints must adhere to Google's validation rules .

      For testing, you can specify URIs that refer to the local machine, such as http://localhost:8080 . With that in mind, please note that all of the examples in this document use http://localhost:8080 as the redirect URI.

      We recommend that you design your app's auth endpoints so that your application does not expose authorization codes to other resources on the page.

    After creating your credentials, download the client_secret.json file from the . Securely store the file in a location that only your application can access.

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

    Scopes enable your application to only request access to the resources that it needs while also enabling users to control the amount of access that they grant to your application. Thus, there may be an inverse relationship between the number of scopes requested and the likelihood of obtaining user consent.

    Before you start implementing OAuth 2.0 authorization, we recommend that you identify the scopes that your app will need permission to access.

    We also recommend that your application request access to authorization scopes via an incremental authorization process, in which your application requests access to user data in context. This best practice helps users to more easily understand why your application needs the access it is requesting.

    The OAuth 2.0 API Scopes document contains a full list of scopes that you might use to access Google APIs.

    Language-specific requirements

    To run any of the code samples in this document, you'll need a Google account, access to the Internet, and a web browser. If you are using one of the API client libraries, also see the language-specific requirements below.

    PHP

    To run the PHP code samples in this document, you'll need:

    • PHP 8.0 or greater with the command-line interface (CLI) and JSON extension installed.
    • The Composer dependency management tool.
    • The Google APIs Client Library for PHP:

      composer require google/apiclient:^2.15.0

    See Google APIs Client Library for PHP for more information.

    پایتون

    To run the Python code samples in this document, you'll need:

    • Python 3.7 or greater
    • The pip package management tool.
    • The Google APIs Client Library for Python 2.0 release:
      pip install --upgrade google-api-python-client
    • The google-auth , google-auth-oauthlib , and google-auth-httplib2 for user authorization.
      pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
    • The Flask Python web application framework.
      pip install --upgrade flask
    • The requests HTTP library.
      pip install --upgrade requests

    Review the Google API Python client library release note if you aren't able to upgrade python and associated migration guide.

    روبی

    To run the Ruby code samples in this document, you'll need:

    • Ruby 2.6 or greater
    • The Google Auth Library for Ruby:

      gem install googleauth
    • The client libraries for Drive and Calendar Google APIs:

      gem install google-apis-drive_v3 google-apis-calendar_v3
    • The Sinatra Ruby web application framework.

      gem install sinatra

    Node.js

    To run the Node.js code samples in this document, you'll need:

    • The maintenance LTS, active LTS, or current release of Node.js.
    • The Google APIs Node.js Client:

      npm install googleapis crypto express express-session

    HTTP/REST

    You do not need to install any libraries to be able to directly call the OAuth 2.0 endpoints.

    Obtaining OAuth 2.0 access tokens

    The following steps show how your application interacts with Google's OAuth 2.0 server to obtain a user's consent to perform an API request on the user's behalf. Your application must have that consent before it can execute a Google API request that requires user authorization.

    The list below quickly summarizes these steps:

    1. Your application identifies the permissions it needs.
    2. Your application redirects the user to Google along with the list of requested permissions.
    3. The user decides whether to grant the permissions to your application.
    4. Your application finds out what the user decided.
    5. If the user granted the requested permissions, your application retrieves tokens needed to make API requests on the user's behalf.

    Step 1: Set authorization parameters

    Your first step is to create the authorization request. That request sets parameters that identify your application and define the permissions that the user will be asked to grant to your application.

    • If you use a Google client library for OAuth 2.0 authentication and authorization, you create and configure an object that defines these parameters.
    • If you call the Google OAuth 2.0 endpoint directly, you'll generate a URL and set the parameters on that URL.

    The tabs below define the supported authorization parameters for web server applications. The language-specific examples also show how to use a client library or authorization library to configure an object that sets those parameters.

    PHP

    The following code snippet creates a Google\Client() object, which defines the parameters in the authorization request.

    That object uses information from your client_secret.json file to identify your application. (See creating authorization credentials for more about that file.) The object also identifies the scopes that your application is requesting permission to access and the URL to your application's auth endpoint, which will handle the response from Google's OAuth 2.0 server. Finally, the code sets the optional access_type and include_granted_scopes parameters.

    For example, this code requests read-only, offline access to a user's Google Drive metadata and Calendar events:

    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\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);
    
    // Required, call the setRedirectUri function to specify a valid redirect URI for the
    // provided client_id
    $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
    
    // Recommended, offline access will give you both an access and refresh token so that
    // your app can refresh the access token without user interaction.
    $client->setAccessType('offline');
    
    // Recommended, call the setState function. Using a state value can increase your assurance that
    // an incoming connection is the result of an authentication request.
    $client->setState($sample_passthrough_value);
    
    // Optional, if your application knows which user is trying to authenticate, it can use this
    // parameter to provide a hint to the Google Authentication Server.
    $client->setLoginHint('hint@example.com');
    
    // Optional, call the setPrompt function to set "consent" will prompt the user for consent
    $client->setPrompt('consent');
    
    // Optional, call the setIncludeGrantedScopes function with true to enable incremental
    // authorization
    $client->setIncludeGrantedScopes(true);

    پایتون

    The following code snippet uses the google-auth-oauthlib.flow module to construct the authorization request.

    The code constructs a Flow object, which identifies your application using information from the client_secret.json file that you downloaded after creating authorization credentials . That object also identifies the scopes that your application is requesting permission to access and the URL to your application's auth endpoint, which will handle the response from Google's OAuth 2.0 server. Finally, the code sets the optional access_type and include_granted_scopes parameters.

    For example, this code requests read-only, offline access to a user's Google Drive metadata and Calendar events:

    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/drive.metadata.readonly',
                'https://www.googleapis.com/auth/calendar.readonly'])
    
    # Required, indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required. The value must exactly
    # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
    # configured in the API Console. If this value doesn't match an authorized URI,
    # you will get a 'redirect_uri_mismatch' error.
    flow.redirect_uri = 'https://www.example.com/oauth2callback'
    
    # Generate URL for request to Google's OAuth 2.0 server.
    # Use kwargs to set optional request parameters.
    authorization_url, state = flow.authorization_url(
        # Recommended, enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Optional, enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true',
        # Optional, if your application knows which user is trying to authenticate, it can use this
        # parameter to provide a hint to the Google Authentication Server.
        login_hint='hint@example.com',
        # Optional, set prompt to 'consent' will prompt the user for consent
        prompt='consent')

    روبی

    Use the client_secrets.json file that you created to configure a client object in your application. When you configure a client object, you specify the scopes your application needs to access, along with the URL to your application's auth endpoint, which will handle the response from the OAuth 2.0 server.

    For example, this code requests read-only, offline access to a user's Google Drive metadata and Calendar events:

    require 'googleauth'
    require 'googleauth/web_user_authorizer'
    require 'googleauth/stores/redis_token_store'
    
    require 'google/apis/drive_v3'
    require 'google/apis/calendar_v3'
    
    # Required, call the from_file method to retrieve the client ID from a
    # client_secret.json file.
    client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')
    
    # Required, scope value 
    # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
             'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']
    
    # Required, Authorizers require a storage instance to manage long term persistence of
    # access and refresh tokens.
    token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
    
    # Required, indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required. The value must exactly
    # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
    # configured in the API Console. If this value doesn't match an authorized URI,
    # you will get a 'redirect_uri_mismatch' error.
    callback_uri = '/oauth2callback'
    
    # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
    # from the client_secret.json file. To get these credentials for your application, visit
    # https://console.cloud.google.com/apis/credentials.
    authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope,
                                                    token_store, callback_uri)

    Your application uses the client object to perform OAuth 2.0 operations, such as generating authorization request URLs and applying access tokens to HTTP requests.

    Node.js

    The following code snippet creates a google.auth.OAuth2 object, which defines the parameters in the authorization request.

    That object uses information from your client_secret.json file to identify your application. To ask for permissions from a user to retrieve an access token, you redirect them to a consent page. To create a consent page URL:

    const {google} = require('googleapis');
    const crypto = require('crypto');
    const express = require('express');
    const session = require('express-session');
    
    /**
     * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
     * from the client_secret.json file. To get these credentials for your application, visit
     * https://console.cloud.google.com/apis/credentials.
     */
    const oauth2Client = new google.auth.OAuth2(
      YOUR_CLIENT_ID,
      YOUR_CLIENT_SECRET,
      YOUR_REDIRECT_URL
    );
    
    // Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    const scopes = [
      'https://www.googleapis.com/auth/drive.metadata.readonly',
      'https://www.googleapis.com/auth/calendar.readonly'
    ];
    
    // Generate a secure random state value.
    const state = crypto.randomBytes(32).toString('hex');
    
    // Store state in the session
    req.session.state = state;
    
    // Generate a url that asks permissions for the Drive activity and Google Calendar scope
    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true,
      // Include the state parameter to reduce the risk of CSRF attacks.
      state: state
    });

    Important Note - The refresh_token is only returned on the first authorization. جزئیات بیشتر در اینجا .

    HTTP/REST

    Google's OAuth 2.0 endpoint is at https://accounts.google.com/o/oauth2/v2/auth . This endpoint is accessible only over HTTPS. Plain HTTP connections are refused.

    The Google authorization server supports the following query string parameters for web server applications:

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

    The client ID for your application. You can find this value in the .

    redirect_uri مورد نیاز

    تعیین می کند که سرور API کاربر را پس از تکمیل جریان مجوز توسط کاربر به کجا هدایت می کند. The value must exactly match one of the authorized redirect URIs for the OAuth 2.0 client, which you configured in your client's . If this value doesn't match an authorized redirect URI for the provided client_id you will get a redirect_uri_mismatch error.

    Note that the http or https scheme, case, and trailing slash (' / ') must all match.

    response_type مورد نیاز

    Determines whether the Google OAuth 2.0 endpoint returns an authorization code.

    Set the parameter value to code for web server applications.

    scope مورد نیاز

    A space-delimited list of scopes that identify the resources that your application could access on the user's behalf. These values inform the consent screen that Google displays to the user.

    Scopes enable your application to only request access to the resources that it needs while also enabling users to control the amount of access that they grant to your application. Thus, there is an inverse relationship between the number of scopes requested and the likelihood of obtaining user consent.

    We recommend that your application request access to authorization scopes in context whenever possible. By requesting access to user data in context, via incremental authorization , you help users to more easily understand why your application needs the access it is requesting.

    access_type توصیه می شود

    Indicates whether your application can refresh access tokens when the user is not present at the browser. Valid parameter values are online , which is the default value, and offline .

    Set the value to offline if your application needs to refresh access tokens when the user is not present at the browser. This is the method of refreshing access tokens described later in this document. This value instructs the Google authorization server to return a refresh token and an access token the first time that your application exchanges an authorization code for tokens.

    state توصیه می شود

    Specifies any string value that your application uses to maintain state between your authorization request and the authorization server's response. The server returns the exact value that you send as a name=value pair in the URL query component ( ? ) of the redirect_uri after the user consents to or denies your application's access request.

    You can use this parameter for several purposes, such as directing the user to the correct resource in your application, sending nonces, and mitigating cross-site request forgery. Since your redirect_uri can be guessed, using a state value can increase your assurance that an incoming connection is the result of an authentication request. If you generate a random string or encode the hash of a cookie or another value that captures the client's state, you can validate the response to additionally ensure that the request and response originated in the same browser, providing protection against attacks such as cross-site request forgery . See the OpenID Connect documentation for an example of how to create and confirm a state token.

    include_granted_scopes اختیاری

    Enables applications to use incremental authorization to request access to additional scopes in context. If you set this parameter's value to true and the authorization request is granted, then the new access token will also cover any scopes to which the user previously granted the application access. See the incremental authorization section for examples.

    login_hint اختیاری

    If your application knows which user is trying to authenticate, it can use this parameter to provide a hint to the Google Authentication Server. The server uses the hint to simplify the login flow either by prefilling the email field in the sign-in form or by selecting the appropriate multi-login session.

    Set the parameter value to an email address or sub identifier, which is equivalent to the user's Google ID.

    prompt اختیاری

    A space-delimited, case-sensitive list of prompts to present the user. If you don't specify this parameter, the user will be prompted only the first time your project requests access. See Prompting re-consent for more information.

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

    none Do not display any authentication or consent screens. Must not be specified with other values.
    consent Prompt the user for consent.
    select_account Prompt the user to select an account.

    Step 2: Redirect to Google's OAuth 2.0 server

    Redirect the user to Google's OAuth 2.0 server to initiate the authentication and authorization process. Typically, this occurs when your application first needs to access the user's data. In the case of incremental authorization , this step also occurs when your application first needs to access additional resources that it does not yet have permission to access.

    PHP

    1. Generate a URL to request access from Google's OAuth 2.0 server:
      $auth_url = $client->createAuthUrl();
    2. Redirect the user to $auth_url :
      header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

    پایتون

    This example shows how to redirect the user to the authorization URL using the Flask web application framework:

    return flask.redirect(authorization_url)

    روبی

    1. Generate a URL to request access from Google's OAuth 2.0 server:
      auth_uri = authorizer.get_authorization_url(request: request)
    2. Redirect the user to auth_uri .

    Node.js

    1. Use the generated URL authorizationUrl from Step 1 generateAuthUrl method to request access from Google's OAuth 2.0 server.
    2. Redirect the user to authorizationUrl .
      res.redirect(authorizationUrl);

    HTTP/REST

    Sample redirect to Google's authorization server

    An example URL is shown below, with line breaks and spaces for readability.

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

    After you create the request URL, redirect the user to it.

    Google's OAuth 2.0 server authenticates the user and obtains consent from the user for your application to access the requested scopes. The response is sent back to your application using the redirect URL you specified.

    Step 3: Google prompts user for consent

    In this step, the user decides whether to grant your application the requested access. At this stage, Google displays a consent window that shows the name of your application and the Google API services that it is requesting permission to access with the user's authorization credentials and a summary of the scopes of access to be granted. The user can then consent to grant access to one or more scopes requested by your application or refuse the request.

    Your application doesn't need to do anything at this stage as it waits for the response from Google's OAuth 2.0 server indicating whether any access was granted. That response is explained in the following step.

    خطاها

    Requests to Google's OAuth 2.0 authorization endpoint may display user-facing error messages instead of the expected authentication and authorization flows. کدهای خطای رایج و راهکارهای پیشنهادی در زیر فهرست شده‌اند.

    admin_policy_enforced

    The Google Account is unable to authorize one or more scopes requested due to the policies of their Google Workspace administrator. See the Google Workspace Admin help article Control which third-party & internal apps access Google Workspace data for more information about how an administrator may restrict access to all scopes or sensitive and restricted scopes until access is explicitly granted to your OAuth client ID.

    disallowed_useragent

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

    اندروید

    Android developers may encounter this error message when opening authorization requests in android.webkit.WebView . توسعه‌دهندگان باید در عوض از کتابخانه‌های Android مانند Google Sign-In برای Android یا OpenID Foundation's AppAuth برای Android استفاده کنند.

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

    iOS

    iOS and macOS developers may encounter this error when opening authorization requests in WKWebView . Developers should instead use iOS libraries such as Google Sign-In for iOS or OpenID Foundation's AppAuth for iOS .

    Web developers may encounter this error when an iOS or macOS app opens a general web link in an embedded user-agent and a user navigates to Google's OAuth 2.0 authorization endpoint from your site. Developers should allow general links to open in the default link handler of the operating system, which includes both Universal Links handlers or the default browser app. The SFSafariViewController library is also a supported option.

    org_internal

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

    invalid_client

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

    invalid_grant

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

    redirect_uri_mismatch

    The redirect_uri passed in the authorization request does not match an authorized redirect URI for the OAuth client ID. Review authorized redirect URIs in the .

    The redirect_uri parameter may refer to the OAuth out-of-band (OOB) flow that has been deprecated and is no longer supported. برای به روز رسانی ادغام خود به راهنمای مهاجرت مراجعه کنید.

    invalid_request

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

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

    Step 4: Handle the OAuth 2.0 server response

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

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

    یک پاسخ خطا:

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

    پاسخ کد مجوز:

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

    Sample OAuth 2.0 server response

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

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

    After completing the OAuth 2.0 flow, you should be redirected to http://localhost/oauth2callback , which will likely yield a 404 NOT FOUND error unless your local machine serves a file at that address. مرحله بعدی جزئیات بیشتری را در مورد اطلاعات بازگردانده شده در URI هنگامی که کاربر به برنامه شما هدایت می شود ارائه می دهد.

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

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

    PHP

    To exchange an authorization code for an access token, use the fetchAccessTokenWithAuthCode method:

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

    پایتون

    On your callback page, use the google-auth library to verify the authorization server response. Then, use the flow.fetch_token method to exchange the authorization code in that response for an access token:

    state = flask.session['state']
    flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
        'client_secret.json',
        scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'],
        state=state)
    flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
    
    authorization_response = flask.request.url
    flow.fetch_token(authorization_response=authorization_response)
    
    # Store the credentials in the session.
    # ACTION ITEM for developers:
    #     Store user's access and refresh tokens in your data store if
    #     incorporating this code into your real app.
    credentials = flow.credentials
    flask.session['credentials'] = {
        'token': credentials.token,
        'refresh_token': credentials.refresh_token,
        'token_uri': credentials.token_uri,
        'client_id': credentials.client_id,
        'client_secret': credentials.client_secret,
        'granted_scopes': credentials.granted_scopes}

    روبی

    On your callback page, use the googleauth library to verify the authorization server response. Use the authorizer.handle_auth_callback_deferred method to save the authorization code and redirect back to the URL that originally requested authorization. This 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

    Node.js

    To exchange an authorization code for an access token, use the getToken method:

    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

    To exchange an authorization code for an access token, call the https://oauth2.googleapis.com/token endpoint and set the following parameters:

    فیلدها
    client_id The client ID obtained from the .
    client_secret The client secret obtained from the .
    code The authorization code returned from the initial request.
    grant_type As defined in the OAuth 2.0 specification , this field's value must be set to authorization_code .
    redirect_uri One of the redirect URIs listed for your project in the for the given client_id .

    The following snippet shows a sample request:

    POST /token HTTP/1.1
    Host: oauth2.googleapis.com
    Content-Type: application/x-www-form-urlencoded
    
    code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
    client_id=your_client_id&
    client_secret=your_client_secret&
    redirect_uri=https%3A//oauth2.example.com/code&
    grant_type=authorization_code

    Google responds to this request by returning a JSON object that contains a short-lived access token and a refresh token. Note that the refresh token is only returned if your application set the access_type parameter to offline in the initial request to Google's authorization server .

    The response contains the following fields:

    فیلدها
    access_token The token that your application sends to authorize a Google API request.
    expires_in The remaining lifetime of the access token in seconds.
    refresh_token A token that you can use to obtain a new access token. Refresh tokens are valid until the user revokes access or the refresh token expires. Again, this field is only present in this response if you set the access_type parameter to offline in the initial request to Google's authorization server.
    refresh_token_expires_in The remaining lifetime of the refresh token in seconds. This value is only set when the user grants time-based access .
    scope The scopes of access granted by the access_token expressed as a list of space-delimited, case-sensitive strings.
    token_type The type of token returned. At this time, this field's value is always set to Bearer .

    The following snippet shows a sample response:

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

    خطاها

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

    invalid_grant

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

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

    When requesting multiple permissions (scopes), users may not grant your app access to all of them. Your app must verify which scopes were actually granted and gracefully handle situations where some permissions are denied, typically by disabling the features that rely on those denied scopes.

    با این حال، استثناهایی وجود دارد. Google Workspace Enterprise apps with domain-wide delegation of authority , or apps marked as Trusted , bypass the granular permissions consent screen. For these apps, users won't see the granular permission consent screen. Instead, your app will either receive all requested scopes or none.

    For more detailed information, see How to handle granular permissions .

    PHP

    To check which scopes the user has granted, use the getGrantedScope() method:

    // Space-separated string of granted scopes if it exists, otherwise null.
    $granted_scopes = $client->getOAuth2Service()->getGrantedScope();
    
    // Determine which scopes user granted and build a dictionary
    $granted_scopes_dict = [
      'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
      'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
    ];

    پایتون

    The returned credentials object has a granted_scopes property, which is a list of scopes the user has granted to your app.

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

    The following function checks which scopes the user has granted to your app.

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

    روبی

    When requesting multiple scopes at once, check which scopes were granted through the scope property of the credentials object.

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

    Node.js

    When requesting multiple scopes at once, check which scopes were granted through the scope property of the tokens object.

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

    HTTP/REST

    To check whether the user has granted your application access to a particular scope, exam the scope field in the access token response. The scopes of access granted by the access_token expressed as a list of space-delimited, case-sensitive strings.

    For example, the following sample access token response indicates that the user has granted your application access to the read-only Drive activity and Calendar events permissions:

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

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

    PHP

    Use the access token to call Google APIs by completing the following steps:

    1. If you need to apply an access token to a new Google\Client object — for example, if you stored the access token in a user session — use the setAccessToken method:
      $client->setAccessToken($access_token);
    2. Build a service object for the API that you want to call. You build a service object by providing an authorized Google\Client object to the constructor for the API you want to call. For example, to call the Drive API:
      $drive = new Google\Service\Drive($client);
    3. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
      $files = $drive->files->listFiles(array());

    پایتون

    After obtaining an access token, your application can use that token to authorize API requests on behalf of a given user account or service account. Use the user-specific authorization credentials to build a service object for the API that you want to call, and then use that object to make authorized API requests.

    1. Build a service object for the API that you want to call. You build a service object by calling the googleapiclient.discovery library's build method with the name and version of the API and the user credentials: For example, to call version 3 of the Drive API:
      from googleapiclient.discovery import build
      
      drive = build('drive', 'v2', credentials=credentials)
    2. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
      files = drive.files().list().execute()

    روبی

    After obtaining an access token, your application can use that token to make API requests on behalf of a given user account or service account. Use the user-specific authorization credentials to build a service object for the API that you want to call, and then use that object to make authorized API requests.

    1. Build a service object for the API that you want to call. For example, to call version 3 of the Drive API:
      drive = Google::Apis::DriveV3::DriveService.new
    2. Set the credentials on the service:
      drive.authorization = credentials
    3. Make requests to the API service using the interface provided by the service object . For example, to list the files in the authenticated user's Google Drive:
      files = drive.list_files

    Alternately, authorization can be provided on a per-method basis by supplying the options parameter to a method:

    files = drive.list_files(options: { authorization: credentials })

    Node.js

    After obtaining an access token and setting it to the OAuth2 object, use the object to call Google APIs. Your application can use that token to authorize API requests on behalf of a given user account or service account. Build a service object for the API that you want to call. For example, the following code uses the Google Drive API to list filenames in the user's Drive.

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

    HTTP/REST

    After your application obtains an access token, you can use the token to make calls to a Google API on behalf of a given user account if the scope(s) of access required by the API have been granted. To do this, include the access token in a request to the API by including either an access_token query parameter or an Authorization HTTP header Bearer value. When possible, the HTTP header is preferable, because query strings tend to be visible in server logs. In most cases you can use a client library to set up your calls to Google APIs (for example, when calling the Drive Files API ).

    You can try out all the Google APIs and view their scopes at the OAuth 2.0 Playground .

    HTTP GET examples

    A call to the drive.files endpoint (the Drive Files API) using the Authorization: Bearer HTTP header might look like the following. Note that you need to specify your own access token:

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

    Here is a call to the same API for the authenticated user using the access_token query string parameter:

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

    curl examples

    You can test these commands with the curl command-line application. Here's an example that uses the HTTP header option (preferred):

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

    Or, alternatively, the query string parameter option:

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

    مثال کامل

    The following example prints a JSON-formatted list of files in a user's Google Drive after the user authenticates and gives consent for the application to access the user's Drive metadata.

    PHP

    To run this example:

    1. در , add the URL of the local machine to the list of redirect URLs. For example, add http://localhost:8080 .
    2. Create a new directory and change to it. به عنوان مثال:
      mkdir ~/php-oauth2-example
      cd ~/php-oauth2-example
    3. Install the Google API Client Library for PHP using Composer :
      composer require google/apiclient:^2.15.0
    4. Create the files index.php and oauth2callback.php with the following content.
    5. Run the example with the PHP's built-in test web server:
      php -S localhost:8080 ~/php-oauth2-example

    index.php

    <?php
    require_once __DIR__.'/vendor/autoload.php';
    
    session_start();
    
    $client = new Google\Client();
    $client->setAuthConfig('client_secret.json');
    
    // User granted permission as an access token is in the session.
    if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
    {
      $client->setAccessToken($_SESSION['access_token']);
      
      // Check if user granted Drive permission
      if ($_SESSION['granted_scopes_dict']['Drive']) {
        echo "Drive feature is enabled.";
        echo "</br>";
        $drive = new Drive($client);
        $files = array();
        $response = $drive->files->listFiles(array());
        foreach ($response->files as $file) {
            echo "File: " . $file->name . " (" . $file->id . ")";
            echo "</br>";
        }
      } else {
        echo "Drive feature is NOT enabled.";
        echo "</br>";
      }
    
       // Check if user granted Calendar permission
      if ($_SESSION['granted_scopes_dict']['Calendar']) {
        echo "Calendar feature is enabled.";
        echo "</br>";
      } else {
        echo "Calendar feature is NOT enabled.";
        echo "</br>";
      }
    }
    else
    {
      // Redirect users to outh2call.php which redirects users to Google OAuth 2.0
      $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
      header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }
    ?>

    oauth2callback.php

    <?php
    require_once __DIR__.'/vendor/autoload.php';
    
    session_start();
    
    $client = new Google\Client();
    
    // Required, call the setAuthConfig function to load authorization credentials from
    // client_secret.json file.
    $client->setAuthConfigFile('client_secret.json');
    $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF']);
    
    // Required, to set the scope value, call the addScope function.
    $client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);
    
    // Enable incremental authorization. Recommended as a best practice.
    $client->setIncludeGrantedScopes(true);
    
    // Recommended, offline access will give you both an access and refresh token so that
    // your app can refresh the access token without user interaction.
    $client->setAccessType("offline");
    
    // Generate a URL for authorization as it doesn't contain code and error
    if (!isset($_GET['code']) && !isset($_GET['error']))
    {
      // Generate and set state value
      $state = bin2hex(random_bytes(16));
      $client->setState($state);
      $_SESSION['state'] = $state;
    
      // Generate a url that asks permissions.
      $auth_url = $client->createAuthUrl();
      header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
    }
    
    // User authorized the request and authorization code is returned to exchange access and
    // refresh tokens.
    if (isset($_GET['code']))
    {
      // Check the state value
      if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) {
        die('State mismatch. Possible CSRF attack.');
      }
    
      // Get access and refresh tokens (if access_type is offline)
      $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
    
      /** Save access and refresh token to the session variables.
        * ACTION ITEM: In a production app, you likely want to save the
        *              refresh token in a secure persistent storage instead. */
      $_SESSION['access_token'] = $token;
      $_SESSION['refresh_token'] = $client->getRefreshToken();
      
      // Space-separated string of granted scopes if it exists, otherwise null.
      $granted_scopes = $client->getOAuth2Service()->getGrantedScope();
    
      // Determine which scopes user granted and build a dictionary
      $granted_scopes_dict = [
        'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
        'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
      ];
      $_SESSION['granted_scopes_dict'] = $granted_scopes_dict;
      
      $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
      header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }
    
    // An error response e.g. error=access_denied
    if (isset($_GET['error']))
    {
      echo "Error: ". $_GET['error'];
    }
    ?>

    پایتون

    This example uses the Flask framework. It runs a web application at http://localhost:8080 that lets you test the OAuth 2.0 flow. If you go to that URL, you should see five links:

    • Call Drive API: This link points to a page that tries to execute a sample API request if users granted the permission. If necessary, it starts the authorization flow. If successful, the page displays the API response.
    • Mock page to call Calendar API: This link points to a maockpage that tries to execute a sample Calendar API request if users granted the permission. If necessary, it starts the authorization flow. If successful, the page displays the API response.
    • Test the auth flow directly: This link points to a page that tries to send the user through the authorization flow . The app requests permission to submit authorized API requests on the user's behalf.
    • Revoke current credentials: This link points to a page that revokes permissions that the user has already granted to the application.
    • Clear Flask session credentials: This link clears authorization credentials that are stored in the Flask session. This lets you see what would happen if a user who had already granted permission to your app tried to execute an API request in a new session. It also lets you see the API response your app would get if a user had revoked permissions granted to your app, and your app still tried to authorize a request with a revoked access token.
    # -*- coding: utf-8 -*-
    
    import os
    import flask
    import requests
    
    import google.oauth2.credentials
    import google_auth_oauthlib.flow
    import googleapiclient.discovery
    
    # This variable specifies the name of a file that contains the OAuth 2.0
    # information for this application, including its client_id and client_secret.
    CLIENT_SECRETS_FILE = "client_secret.json"
    
    # The OAuth 2.0 access scope allows for access to the
    # authenticated user's account and requires requests to use an SSL connection.
    SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly',
              'https://www.googleapis.com/auth/calendar.readonly']
    API_SERVICE_NAME = 'drive'
    API_VERSION = 'v2'
    
    app = flask.Flask(__name__)
    # Note: A secret key is included in the sample so that it works.
    # If you use this code in your application, replace this with a truly secret
    # key. See https://flask.palletsprojects.com/quickstart/#sessions.
    app.secret_key = 'REPLACE ME - this value is here as a placeholder.'
    
    @app.route('/')
    def index():
      return print_index_table()
    
    @app.route('/drive')
    def drive_api_request():
      if 'credentials' not in flask.session:
        return flask.redirect('authorize')
    
      features = flask.session['features']
    
      if features['drive']:
        # Load credentials from the session.
        credentials = google.oauth2.credentials.Credentials(
            **flask.session['credentials'])
    
        drive = googleapiclient.discovery.build(
            API_SERVICE_NAME, API_VERSION, credentials=credentials)
    
        files = drive.files().list().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(**files)
      else:
        # User didn't authorize read-only Drive activity permission.
        # Update UX and application accordingly
        return '<p>Drive feature is not enabled.</p>'
    
    @app.route('/calendar')
        def calendar_api_request():
          if 'credentials' not in flask.session:
            return flask.redirect('authorize')
    
          features = flask.session['features']
    
          if features['calendar']:
            # User authorized Calendar read permission.
            # Calling the APIs, etc.
            return ('<p>User granted the Google Calendar read permission. '+
                    'This sample code does not include code to call Calendar</p>')
          else:
            # User didn't authorize Calendar read permission.
            # Update UX and application accordingly
            return '<p>Calendar feature is not enabled.</p>'
    
    @app.route('/authorize')
    def authorize():
      # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
      flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
          CLIENT_SECRETS_FILE, scopes=SCOPES)
    
      # The URI created here must exactly match one of the authorized redirect URIs
      # for the OAuth 2.0 client, which you configured in the API Console. If this
      # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
      # error.
      flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
    
      authorization_url, state = flow.authorization_url(
          # Enable offline access so that you can refresh an access token without
          # re-prompting the user for permission. Recommended for web server apps.
          access_type='offline',
          # Enable incremental authorization. Recommended as a best practice.
          include_granted_scopes='true')
    
      # Store the state so the callback can verify the auth server response.
      flask.session['state'] = state
    
      return flask.redirect(authorization_url)
    
    @app.route('/oauth2callback')
    def oauth2callback():
      # Specify the state when creating the flow in the callback so that it can
      # verified in the authorization server response.
      state = flask.session['state']
    
      flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
          CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
      flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
    
      # Use the authorization server's response to fetch the OAuth 2.0 tokens.
      authorization_response = flask.request.url
      flow.fetch_token(authorization_response=authorization_response)
    
      # Store credentials in the session.
      # ACTION ITEM: In a production app, you likely want to save these
      #              credentials in a persistent database instead.
      credentials = flow.credentials
      
      credentials = credentials_to_dict(credentials)
      flask.session['credentials'] = credentials
    
      # Check which scopes user granted
      features = check_granted_scopes(credentials)
      flask.session['features'] = features
      return flask.redirect('/')
      
    
    @app.route('/revoke')
    def revoke():
      if 'credentials' not in flask.session:
        return ('You need to <a href="/authorize">authorize</a> before ' +
                'testing the code to revoke credentials.')
    
      credentials = google.oauth2.credentials.Credentials(
        **flask.session['credentials'])
    
      revoke = requests.post('https://oauth2.googleapis.com/revoke',
          params={'token': credentials.token},
          headers = {'content-type': 'application/x-www-form-urlencoded'})
    
      status_code = getattr(revoke, 'status_code')
      if status_code == 200:
        return('Credentials successfully revoked.' + print_index_table())
      else:
        return('An error occurred.' + print_index_table())
    
    @app.route('/clear')
    def clear_credentials():
      if 'credentials' in flask.session:
        del flask.session['credentials']
      return ('Credentials have been cleared.<br><br>' +
              print_index_table())
    
    def credentials_to_dict(credentials):
      return {'token': credentials.token,
              'refresh_token': credentials.refresh_token,
              'token_uri': credentials.token_uri,
              'client_id': credentials.client_id,
              'client_secret': credentials.client_secret,
              'granted_scopes': credentials.granted_scopes}
    
    def check_granted_scopes(credentials):
      features = {}
      if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']:
        features['drive'] = True
      else:
        features['drive'] = False
    
      if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']:
        features['calendar'] = True
      else:
        features['calendar'] = False
    
      return features
    
    def print_index_table():
      return ('<table>' +
              '<tr><td><a href="/test">Test an API request</a></td>' +
              '<td>Submit an API request and see a formatted JSON response. ' +
              '    Go through the authorization flow if there are no stored ' +
              '    credentials for the user.</td></tr>' +
              '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
              '<td>Go directly to the authorization flow. If there are stored ' +
              '    credentials, you still might not be prompted to reauthorize ' +
              '    the application.</td></tr>' +
              '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
              '<td>Revoke the access token associated with the current user ' +
              '    session. After revoking credentials, if you go to the test ' +
              '    page, you should see an <code>invalid_grant</code> error.' +
              '</td></tr>' +
              '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
              '<td>Clear the access token currently stored in the user session. ' +
              '    After clearing the token, if you <a href="/test">test the ' +
              '    API request</a> again, you should go back to the auth flow.' +
              '</td></tr></table>')
    
    if __name__ == '__main__':
      # When running locally, disable OAuthlib's HTTPs verification.
      # ACTION ITEM for developers:
      #     When running in production *do not* leave this option enabled.
      os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
    
      # This disables the requested scopes and granted scopes check.
      # If users only grant partial request, the warning would not be thrown.
      os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'
    
      # Specify a hostname and port that are set as a valid redirect URI
      # for your API project in the .
      app.run('localhost', 8080, debug=True)

    روبی

    This example uses the Sinatra framework.

    require 'googleauth'
    require 'googleauth/web_user_authorizer'
    require 'googleauth/stores/redis_token_store'
    
    require 'google/apis/drive_v3'
    require 'google/apis/calendar_v3'
    
    require 'sinatra'
    
    configure do
      enable :sessions
    
      # Required, call the from_file method to retrieve the client ID from a
      # client_secret.json file.
      set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')
    
      # Required, scope value
      # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
      scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
               'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']
    
      # Required, Authorizers require a storage instance to manage long term persistence of
      # access and refresh tokens.
      set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
    
      # Required, indicate where the API server will redirect the user after the user completes
      # the authorization flow. The redirect URI is required. The value must exactly
      # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
      # configured in the API Console. If this value doesn't match an authorized URI,
      # you will get a 'redirect_uri_mismatch' error.
      set :callback_uri, '/oauth2callback'
    
      # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
      # from the client_secret.json file. To get these credentials for your application, visit
      # https://console.cloud.google.com/apis/credentials.
      set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope,
                              settings.token_store, callback_uri: settings.callback_uri)
    end
    
    get '/' do
      # NOTE: Assumes the user is already authenticated to the app
      user_id = request.session['user_id']
    
      # Fetch stored credentials for the user from the given request session.
      # nil if none present
      credentials = settings.authorizer.get_credentials(user_id, request)
    
      if credentials.nil?
        # Generate a url that asks the user to authorize requested scope(s).
        # Then, redirect user to the url.
        redirect settings.authorizer.get_authorization_url(request: request)
      end
      
      # User authorized the request. Now, check which scopes were granted.
      if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)
        # User authorized read-only Drive activity permission.
        # Example of using Google Drive API to list filenames in user's Drive.
        drive = Google::Apis::DriveV3::DriveService.new
        files = drive.list_files(options: { authorization: credentials })
        "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
      else
        # User didn't authorize read-only Drive activity permission.
        # Update UX and application accordingly
      end
    
      # Check if user authorized Calendar read permission.
      if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)
        # User authorized Calendar read permission.
        # Calling the APIs, etc.
      else
        # User didn't authorize Calendar read permission.
        # Update UX and application accordingly
      end
    end
    
    # Receive the callback from Google's OAuth 2.0 server.
    get '/oauth2callback' do
      # Handle the result of the oauth callback. Defers the exchange of the code by
      # temporarily stashing the results in the user's session.
      target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
      redirect target_url
    end

    Node.js

    To run this example:

    1. در , add the URL of the local machine to the list of redirect URLs. For example, add http://localhost .
    2. Make sure you have maintenance LTS, active LTS, or current release of Node.js installed.
    3. Create a new directory and change to it. به عنوان مثال:
      mkdir ~/nodejs-oauth2-example
      cd ~/nodejs-oauth2-example
    4. Install the Google API Client Library for Node.js using npm :
      npm install googleapis
    5. Create the files main.js with the following content.
    6. Run the example:
      node .\main.js

    main.js

    const http = require('http');
    const https = require('https');
    const url = require('url');
    const { google } = require('googleapis');
    const crypto = require('crypto');
    const express = require('express');
    const session = require('express-session');
    
    /**
     * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
     * To get these credentials for your application, visit
     * https://console.cloud.google.com/apis/credentials.
     */
    const oauth2Client = new google.auth.OAuth2(
      YOUR_CLIENT_ID,
      YOUR_CLIENT_SECRET,
      YOUR_REDIRECT_URL
    );
    
    // Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    const scopes = [
      'https://www.googleapis.com/auth/drive.metadata.readonly',
      'https://www.googleapis.com/auth/calendar.readonly'
    ];
    
    /* Global variable that stores user credential in this code example.
     * ACTION ITEM for developers:
     *   Store user's refresh token in your data store if
     *   incorporating this code into your real app.
     *   For more information on handling refresh tokens,
     *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
     */
    let userCredential = null;
    
    async function main() {
      const app = express();
    
      app.use(session({
        secret: 'your_secure_secret_key', // Replace with a strong secret
        resave: false,
        saveUninitialized: false,
      }));
    
      // Example on redirecting user to Google's OAuth 2.0 server.
      app.get('/', async (req, res) => {
        // Generate a secure random state value.
        const state = crypto.randomBytes(32).toString('hex');
        // Store state in the session
        req.session.state = state;
    
        // Generate a url that asks permissions for the Drive activity and Google Calendar scope
        const authorizationUrl = oauth2Client.generateAuthUrl({
          // 'online' (default) or 'offline' (gets refresh_token)
          access_type: 'offline',
          /** Pass in the scopes array defined above.
            * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
          scope: scopes,
          // Enable incremental authorization. Recommended as a best practice.
          include_granted_scopes: true,
          // Include the state parameter to reduce the risk of CSRF attacks.
          state: state
        });
    
        res.redirect(authorizationUrl);
      });
    
      // Receive the callback from Google's OAuth 2.0 server.
      app.get('/oauth2callback', async (req, res) => {
        // Handle the OAuth 2.0 server response
        let q = url.parse(req.url, true).query;
    
        if (q.error) { // An error response e.g. error=access_denied
          console.log('Error:' + q.error);
        } else if (q.state !== req.session.state) { //check state value
          console.log('State mismatch. Possible CSRF attack');
          res.end('State mismatch. Possible CSRF attack');
        } else { // Get access and refresh tokens (if access_type is offline)
          let { tokens } = await oauth2Client.getToken(q.code);
          oauth2Client.setCredentials(tokens);
    
          /** Save credential to the global variable in case access token was refreshed.
            * ACTION ITEM: In a production app, you likely want to save the refresh token
            *              in a secure persistent database instead. */
          userCredential = tokens;
          
          // User authorized the request. Now, check which scopes were granted.
          if (tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly'))
          {
            // User authorized read-only Drive activity permission.
            // Example of using Google Drive API to list filenames in user's Drive.
            const drive = google.drive('v3');
            drive.files.list({
              auth: oauth2Client,
              pageSize: 10,
              fields: 'nextPageToken, files(id, name)',
            }, (err1, res1) => {
              if (err1) return console.log('The API returned an error: ' + err1);
              const files = res1.data.files;
              if (files.length) {
                console.log('Files:');
                files.map((file) => {
                  console.log(`${file.name} (${file.id})`);
                });
              } else {
                console.log('No files found.');
              }
            });
          }
          else
          {
            // User didn't authorize read-only Drive activity permission.
            // Update UX and application accordingly
          }
    
          // Check if user authorized Calendar read permission.
          if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
          {
            // User authorized Calendar read permission.
            // Calling the APIs, etc.
          }
          else
          {
            // User didn't authorize Calendar read permission.
            // Update UX and application accordingly
          }
        }
      });
    
      // Example on revoking a token
      app.get('/revoke', async (req, res) => {
        // Build the string for the POST request
        let postData = "token=" + userCredential.access_token;
    
        // Options for POST request to Google's OAuth 2.0 server to revoke a token
        let postOptions = {
          host: 'oauth2.googleapis.com',
          port: '443',
          path: '/revoke',
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': Buffer.byteLength(postData)
          }
        };
    
        // Set up the request
        const postReq = https.request(postOptions, function (res) {
          res.setEncoding('utf8');
          res.on('data', d => {
            console.log('Response: ' + d);
          });
        });
    
        postReq.on('error', error => {
          console.log(error)
        });
    
        // Post the request with data
        postReq.write(postData);
        postReq.end();
      });
    
    
      const server = http.createServer(app);
      server.listen(8080);
    }
    main().catch(console.error);

    HTTP/REST

    This Python example uses the Flask framework and the Requests library to demonstrate the OAuth 2.0 web flow. We recommend using the Google API Client Library for Python for this flow. (The example in the Python tab does use the client library.)

    import json
    import flask
    import requests
    
    app = flask.Flask(__name__)
    
    # To get these credentials (CLIENT_ID CLIENT_SECRET) and for your application, visit
    # https://console.cloud.google.com/apis/credentials.
    CLIENT_ID = '123456789.apps.googleusercontent.com'
    CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app
    
    # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
    SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly'
    
    # Indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required. The value must exactly
    # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
    # configured in the API Console. If this value doesn't match an authorized URI,
    # you will get a 'redirect_uri_mismatch' error.
    REDIRECT_URI = 'http://example.com/oauth2callback'
    
    @app.route('/')
    def index():
      if 'credentials' not in flask.session:
        return flask.redirect(flask.url_for('oauth2callback'))
    
      credentials = json.loads(flask.session['credentials'])
    
      if credentials['expires_in'] <= 0:
        return flask.redirect(flask.url_for('oauth2callback'))
      else: 
        # User authorized the request. Now, check which scopes were granted.
        if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['scope']:
          # User authorized read-only Drive activity permission.
          # Example of using Google Drive API to list filenames in user's Drive.
          headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
          req_uri = 'https://www.googleapis.com/drive/v2/files'
          r = requests.get(req_uri, headers=headers).text
        else:
          # User didn't authorize read-only Drive activity permission.
          # Update UX and application accordingly
          r = 'User did not authorize Drive permission.'
    
        # Check if user authorized Calendar read permission.
        if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['scope']:
          # User authorized Calendar read permission.
          # Calling the APIs, etc.
          r += 'User authorized Calendar permission.'
        else:
          # User didn't authorize Calendar read permission.
          # Update UX and application accordingly
          r += 'User did not authorize Calendar permission.'
    
      return r
    
    @app.route('/oauth2callback')
    def oauth2callback():
      if 'code' not in flask.request.args:
        state = str(uuid.uuid4())
        flask.session['state'] = state
        # Generate a url that asks permissions for the Drive activity
        # and Google Calendar scope. Then, redirect user to the url.
        auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                    '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI,
                                                                              SCOPE, state)
        return flask.redirect(auth_uri)
      else:
        if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']:
          return 'State mismatch. Possible CSRF attack.', 400
    
        auth_code = flask.request.args.get('code')
        data = {'code': auth_code,
                'client_id': CLIENT_ID,
                'client_secret': CLIENT_SECRET,
                'redirect_uri': REDIRECT_URI,
                'grant_type': 'authorization_code'}
    
        # Exchange authorization code for access and refresh tokens (if access_type is offline)
        r = requests.post('https://oauth2.googleapis.com/token', data=data)
        flask.session['credentials'] = r.text
        return flask.redirect(flask.url_for('index'))
    
    if __name__ == '__main__':
      import uuid
      app.secret_key = str(uuid.uuid4())
      app.debug = False
      app.run()

    Redirect URI validation rules

    Google applies the following validation rules to redirect URIs in order to help developers keep their applications secure. Your redirect URIs must adhere to these rules. See RFC 3986 section 3 for the definition of domain, host, path, query, scheme and userinfo, mentioned below.

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

    Redirect URIs must use the HTTPS scheme, not plain HTTP. Localhost URIs (including localhost IP address URIs) are exempt from this rule.

    میزبان

    Hosts cannot be raw IP addresses. Localhost IP addresses are exempted from this rule.

    دامنه
  • Host TLDs ( Top Level Domains ) must belong to the public suffix list .
  • Host domains cannot be “googleusercontent.com” .
  • Redirect URIs cannot contain URL shortener domains (eg goo.gl ) unless the app owns the domain. Furthermore, if an app that owns a shortener domain chooses to redirect to that domain, that redirect URI must either contain “/google-callback/” in its path or end with “/google-callback” .
  • اطلاعات کاربری

    Redirect URIs cannot contain the userinfo subcomponent.

    مسیر

    Redirect URIs cannot contain a path traversal (also called directory backtracking), which is represented by an “/..” or “\..” or their URL encoding.

    پرس و جو

    Redirect URIs cannot contain open redirects .

    قطعه

    Redirect URIs cannot contain the fragment component.

    شخصیت ها Redirect URIs cannot contain certain characters including:
    • Wildcard characters ( '*' )
    • کاراکترهای ASCII غیر قابل چاپ
    • Invalid percent encodings (any percent encoding that does not follow URL-encoding form of a percent sign followed by two hexadecimal digits)
    • Null characters (an encoded NULL character, eg, %00 , %C0%80 )

    مجوز افزایشی

    In the OAuth 2.0 protocol, your app requests authorization to access resources, which are identified by scopes. It is considered a best user-experience practice to request authorization for resources at the time you need them. To enable that practice, Google's authorization server supports incremental authorization. This feature lets you request scopes as they are needed and, if the user grants permission for the new scope, returns an authorization code that may be exchanged for a token containing all scopes the user has granted the project.

    For example, an app that lets people sample music tracks and create mixes might need very few resources at sign-in time, perhaps nothing more than the name of the person signing in. However, saving a completed mix would require access to their Google Drive. Most people would find it natural if they only were asked for access to their Google Drive at the time the app actually needed it.

    In this case, at sign-in time the app might request the openid and profile scopes to perform basic sign-in, and then later request the https://www.googleapis.com/auth/drive.file scope at the time of the first request to save a mix.

    To implement incremental authorization, you complete the normal flow for requesting an access token but make sure that the authorization request includes previously granted scopes. This approach allows your app to avoid having to manage multiple access tokens.

    The following rules apply to an access token obtained from an incremental authorization:

    • The token can be used to access resources corresponding to any of the scopes rolled into the new, combined authorization.
    • When you use the refresh token for the combined authorization to obtain an access token, the access token represents the combined authorization and can be used for any of the scope values included in the response.
    • The combined authorization includes all scopes that the user granted to the API project even if the grants were requested from different clients. For example, if a user granted access to one scope using an application's desktop client and then granted another scope to the same application via a mobile client, the combined authorization would include both scopes.
    • If you revoke a token that represents a combined authorization, access to all of that authorization's scopes on behalf of the associated user are revoked simultaneously.

    The language-specific code samples in Step 1: Set authorization parameters and the sample HTTP/REST redirect URL in Step 2: Redirect to Google's OAuth 2.0 server all use incremental authorization. The code samples below also show the code that you need to add to use incremental authorization.

    PHP

    $client->setIncludeGrantedScopes(true);

    پایتون

    In Python, set the include_granted_scopes keyword argument to true to ensure that an authorization request includes previously granted scopes. It is very possible that include_granted_scopes will not be the only keyword argument that you set, as shown in the example below.

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

    روبی

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

    Node.js

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

    HTTP/REST

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

    Refreshing an access token (offline access)

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

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

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

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

    PHP

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

    $client->setAccessType("offline");

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    پایتون

    In Python, set the access_type keyword argument to offline to ensure that you will be able to refresh the access token without having to re-prompt the user for permission. It is very possible that access_type will not be the only keyword argument that you set, as shown in the example below.

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

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    روبی

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

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

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    Node.js

    If your application needs offline access to a Google API, set the API client's access type to 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
    });

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    Access tokens expire. This library will automatically use a refresh token to obtain a new access token if it is about to expire. یک راه آسان برای اطمینان از اینکه همیشه جدیدترین نشانه‌ها را ذخیره می‌کنید، استفاده از رویداد نشانه‌ها است:

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

    This tokens event only occurs in the first authorization, and you need to have set your access_type to offline when calling the generateAuthUrl method to receive the refresh token. If you have already given your app the requisiste permissions without setting the appropriate constraints for receiving a refresh token, you will need to re-authorize the application to receive a fresh refresh token.

    To set the refresh_token at a later time, you can use the setCredentials method:

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

    Once the client has a refresh token, access tokens will be acquired and refreshed automatically in the next call to the API.

    HTTP/REST

    To refresh an access token, your application sends an HTTPS POST request to Google's authorization server ( https://oauth2.googleapis.com/token ) that includes the following parameters:

    فیلدها
    client_id The client ID obtained from the .
    client_secret The client secret obtained from the .
    grant_type As defined in the OAuth 2.0 specification , this field's value must be set to refresh_token .
    refresh_token The refresh token returned from the authorization code exchange.

    The following snippet shows a sample request:

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

    As long as the user has not revoked the access granted to the application, the token server returns a JSON object that contains a new access token. The following snippet shows a sample response:

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

    Note that there are limits on the number of refresh tokens that will be issued; one limit per client/user combination, and another per user across all clients. You should save refresh tokens in long-term storage and continue to use them as long as they remain valid. If your application requests too many refresh tokens, it may run into these limits, in which case older refresh tokens will stop working.

    Revoking a token

    In some cases a user may wish to revoke access given to an application. A user can revoke access by visiting Account Settings . See the Remove site or app access section of the Third-party sites & apps with access to your account support document for more information.

    It is also possible for an application to programmatically revoke the access given to it. Programmatic revocation is important in instances where a user unsubscribes, removes an application, or the API resources required by an app have significantly changed. In other words, part of the removal process can include an API request to ensure the permissions previously granted to the application are removed.

    PHP

    To programmatically revoke a token, call revokeToken() :

    $client->revokeToken();

    پایتون

    To programmatically revoke a token, make a request to https://oauth2.googleapis.com/revoke that includes the token as a parameter and sets the Content-Type header:

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

    روبی

    To programmatically revoke a token, make an HTTP request to the oauth2.revoke endpoint:

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

    The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the status code of the response is 200 . For error conditions, a status code 400 is returned along with an error code.

    Node.js

    To programmatically revoke a token, make an HTTPS POST request to /revoke endpoint:

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

    The token parameter can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the status code of the response is 200 . For error conditions, a status code 400 is returned along with an error code.

    HTTP/REST

    To programmatically revoke a token, your application makes a request to https://oauth2.googleapis.com/revoke and includes the token as a parameter:

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

    The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the HTTP status code of the response is 200 . For error conditions, an HTTP status code 400 is returned along with an error code.

    Time-based access

    Time-based access allows a user to grant your app access to their data for a limited duration to complete an action. Time-based access is available in select Google products during the consent flow, giving users the option to grant access for a limited period of time. An example is the Data Portability API which enables a one-time transfer of data.

    When a user grants your application time-based access, the refresh token will expire after the specified duration. Note that refresh tokens may be invalidated earlier under specific circumstances; see these cases for details. The refresh_token_expires_in field returned in the authorization code exchange response represents the time remaining until the refresh token expires in such cases.

    Implementing Cross-Account Protection

    An additional step you should take to protect your users' accounts is implementing Cross-Account Protection by utilizing Google's Cross-Account Protection Service. This service lets you subscribe to security event notifications which provide information to your application about major changes to the user account. You can then use the information to take action depending on how you decide to respond to events.

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

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