वेब सर्वर ऐप्लिकेशन के लिए OAuth 2.0 का इस्तेमाल करना

इस दस्तावेज़ में बताया गया है कि वेब सर्वर ऐप्लिकेशन, Google API को ऐक्सेस करने के लिए, OAuth 2.0 की अनुमति को कैसे लागू करते हैं. इसके लिए, वे Google API क्लाइंट लाइब्रेरी या Google OAuth 2.0 एंडपॉइंट का इस्तेमाल करते हैं.

OAuth 2.0 की मदद से, उपयोगकर्ता किसी ऐप्लिकेशन के साथ चुनिंदा डेटा शेयर कर सकते हैं. साथ ही, अपने उपयोगकर्ता नाम, पासवर्ड, और अन्य जानकारी को निजी रख सकते हैं. उदाहरण के लिए, कोई ऐप्लिकेशन OAuth 2.0 का इस्तेमाल करके, उपयोगकर्ताओं से उनकी Google Drive में फ़ाइलें सेव करने की अनुमति ले सकता है.

यह OAuth 2.0 फ़्लो, खास तौर पर उपयोगकर्ता की अनुमति के लिए है. इसे ऐसे ऐप्लिकेशन के लिए डिज़ाइन किया गया है जो गोपनीय जानकारी को सेव कर सकते हैं और स्थिति को बनाए रख सकते हैं. सही तरीके से अनुमति वाला वेब सर्वर ऐप्लिकेशन, एपीआई को ऐक्सेस कर सकता है. ऐसा तब होता है, जब उपयोगकर्ता ऐप्लिकेशन के साथ इंटरैक्ट करता है या उपयोगकर्ता ऐप्लिकेशन को छोड़ देता है.

वेब सर्वर ऐप्लिकेशन, एपीआई अनुरोधों को अनुमति देने के लिए, अक्सर सेवा खातों का भी इस्तेमाल करते हैं. खास तौर पर, उपयोगकर्ता के डेटा के बजाय प्रोजेक्ट के डेटा को ऐक्सेस करने के लिए, Cloud API को कॉल करते समय ऐसा किया जाता है. वेब सर्वर ऐप्लिकेशन, उपयोगकर्ता की अनुमति के साथ सेवा खातों का इस्तेमाल कर सकते हैं.

क्लाइंट लाइब्रेरी

इस पेज पर, भाषा के हिसाब से दिए गए उदाहरणों में, OAuth 2.0 की अनुमति लागू करने के लिए, Google API की क्लाइंट लाइब्रेरी का इस्तेमाल किया गया है. कोड सैंपल चलाने के लिए, आपको पहले अपनी भाषा के लिए क्लाइंट लाइब्रेरी इंस्टॉल करनी होगी.

जब अपने ऐप्लिकेशन के OAuth 2.0 फ़्लो को मैनेज करने के लिए, Google API क्लाइंट लाइब्रेरी का इस्तेमाल किया जाता है, तो क्लाइंट लाइब्रेरी ऐसी कई कार्रवाइयां करती है जिन्हें ऐप्लिकेशन को खुद मैनेज करना पड़ता. उदाहरण के लिए, इससे यह तय होता है कि ऐप्लिकेशन, सेव किए गए ऐक्सेस टोकन का इस्तेमाल या उन्हें रीफ़्रेश कब कर सकता है. साथ ही, यह भी तय होता है कि ऐप्लिकेशन को सहमति फिर से कब लेनी होगी. क्लाइंट लाइब्रेरी, सही रीडायरेक्ट यूआरएल भी जनरेट करती है. साथ ही, रीडायरेक्ट हैंडलर लागू करने में मदद करती है. ये हैंडलर, ऑथराइज़ेशन कोड को ऐक्सेस टोकन से बदलते हैं.

सर्वर-साइड ऐप्लिकेशन के लिए, Google API की क्लाइंट लाइब्रेरी इन भाषाओं में उपलब्ध हैं:

ज़रूरी शर्तें

अपने प्रोजेक्ट के लिए एपीआई चालू करना

Google API को कॉल करने वाले किसी भी ऐप्लिकेशन को, API Console में उन एपीआई को चालू करना होगा.

अपने प्रोजेक्ट के लिए कोई एपीआई चालू करने के लिए:

  1. Google API Console में एपीआई लाइब्रेरी खोलें.
  2. अगर कहा जाए, तो कोई प्रोजेक्ट चुनें या नया प्रोजेक्ट बनाएं.
  3. एपीआई लाइब्रेरी में, उपलब्ध सभी एपीआई की सूची होती है. इन्हें प्रॉडक्ट फ़ैमिली और लोकप्रियता के हिसाब से ग्रुप में बांटा जाता है. अगर आपको सूची में वह एपीआई नहीं दिख रहा है जिसे आपको चालू करना है, तो उसे ढूंढने के लिए खोज सुविधा का इस्तेमाल करें. इसके अलावा, उस प्रॉडक्ट फ़ैमिली में सभी देखें पर क्लिक करें जिससे वह एपीआई जुड़ा है.
  4. आपको जो एपीआई चालू करना है उसे चुनें. इसके बाद, चालू करें बटन पर क्लिक करें.
  5. अगर कहा जाए, तो बिलिंग की सुविधा चालू करें.
  6. अगर कहा जाए, तो एपीआई की सेवा की शर्तें पढ़ें और उन्हें स्वीकार करें.

अनुमति देने के लिए क्रेडेंशियल बनाना

Google API को ऐक्सेस करने के लिए, OAuth 2.0 का इस्तेमाल करने वाले हर ऐप्लिकेशन के पास अनुमति देने वाले क्रेडेंशियल होने चाहिए. इनसे Google के OAuth 2.0 सर्वर को ऐप्लिकेशन की पहचान करने में मदद मिलती है. यहां अपने प्रोजेक्ट के लिए क्रेडेंशियल बनाने का तरीका बताया गया है. इसके बाद, आपके ऐप्लिकेशन उन एपीआई को ऐक्सेस करने के लिए क्रेडेंशियल का इस्तेमाल कर सकते हैं जिन्हें आपने उस प्रोजेक्ट के लिए चालू किया है.

  1. क्लाइंट पेज पर जाएं.
  2. क्लाइंट बनाएं पर क्लिक करें.
  3. ऐप्लिकेशन टाइप के तौर पर, वेब ऐप्लिकेशन चुनें.
  4. फ़ॉर्म भरें और बनाएं पर क्लिक करें. PHP, Java, Python, Ruby, और .NET जैसी भाषाओं और फ़्रेमवर्क का इस्तेमाल करने वाले ऐप्लिकेशन को, अनुमति वाले रीडायरेक्ट यूआरआई की जानकारी देनी होगी. रीडायरेक्ट यूआरआई, वे एंडपॉइंट होते हैं जिन पर OAuth 2.0 सर्वर, जवाब भेज सकता है. इन एंडपॉइंट को Google की पुष्टि करने के नियमों का पालन करना चाहिए.

    टेस्टिंग के लिए, लोकल मशीन को रेफ़र करने वाले यूआरआई तय किए जा सकते हैं. जैसे, http://localhost:8080. इस दस्तावेज़ में दिए गए सभी उदाहरणों में, रीडायरेक्ट यूआरआई के तौर पर http://localhost:8080 का इस्तेमाल किया गया है.

    हमारा सुझाव है कि आप अपने ऐप्लिकेशन के ऑथराइज़ेशन एंडपॉइंट को इस तरह डिज़ाइन करें कि आपका ऐप्लिकेशन, पेज पर मौजूद अन्य संसाधनों को ऑथराइज़ेशन कोड न दिखाए.

क्रेडेंशियल बनाने के बाद, API Console से client_secret.json फ़ाइल डाउनलोड करें. फ़ाइल को किसी ऐसी जगह पर सुरक्षित तरीके से सेव करें जिसे सिर्फ़ आपका ऐप्लिकेशन ऐक्सेस कर सके.

ऐक्सेस के स्कोप की पहचान करना

स्कोप की मदद से, आपका ऐप्लिकेशन सिर्फ़ उन संसाधनों को ऐक्सेस करने का अनुरोध कर सकता है जिनकी उसे ज़रूरत है. साथ ही, उपयोगकर्ताओं को यह कंट्रोल करने की सुविधा मिलती है कि वे आपके ऐप्लिकेशन को कितना ऐक्सेस दें. इसलिए, अनुरोध किए गए स्कोप की संख्या और उपयोगकर्ता की सहमति मिलने की संभावना के बीच, उलटा संबंध हो सकता है.

OAuth 2.0 ऑथराइज़ेशन लागू करने से पहले, हमारा सुझाव है कि आप उन स्कोप की पहचान करें जिन्हें ऐक्सेस करने के लिए, आपके ऐप्लिकेशन को अनुमति की ज़रूरत होगी.

हमारा यह भी सुझाव है कि आपका ऐप्लिकेशन, इंक्रीमेंटल ऑथराइज़ेशन प्रोसेस के ज़रिए, ऑथराइज़ेशन के स्कोप को ऐक्सेस करने का अनुरोध करे. इस प्रोसेस में, आपका ऐप्लिकेशन ज़रूरत के मुताबिक उपयोगकर्ता के डेटा को ऐक्सेस करने का अनुरोध करता है. इस सबसे सही तरीके से, उपयोगकर्ताओं को यह समझने में आसानी होती है कि आपके ऐप्लिकेशन को उस ऐक्सेस की ज़रूरत क्यों है जिसके लिए वह अनुरोध कर रहा है.

OAuth 2.0 API के दायरे वाले दस्तावेज़ में, उन सभी दायरों की सूची होती है जिनका इस्तेमाल Google API को ऐक्सेस करने के लिए किया जा सकता है.

भाषा के हिसाब से ज़रूरी शर्तें

इस दस्तावेज़ में दिए गए किसी भी कोड सैंपल को चलाने के लिए, आपके पास Google खाता, इंटरनेट का ऐक्सेस, और वेब ब्राउज़र होना चाहिए. अगर किसी एपीआई क्लाइंट लाइब्रेरी का इस्तेमाल किया जा रहा है, तो यहां दिए गए सेक्शन में भाषा के हिसाब से ज़रूरी शर्तें भी देखें.

PHP

इस दस्तावेज़ में दिए गए PHP कोड सैंपल को चलाने के लिए, आपको इनकी ज़रूरत होगी:

  • PHP 8.0 या इसके बाद का वर्शन, जिसमें कमांड-लाइन इंटरफ़ेस (सीएलआई) और JSON एक्सटेंशन इंस्टॉल हो.
  • Composer डिपेंडेंसी मैनेजमेंट टूल.
  • PHP के लिए Google APIs क्लाइंट लाइब्रेरी:

    composer require google/apiclient:^2.15.0

ज़्यादा जानकारी के लिए, PHP के लिए Google API की क्लाइंट लाइब्रेरी देखें.

Python

इस दस्तावेज़ में दिए गए Python कोड सैंपल चलाने के लिए, आपको इनकी ज़रूरत होगी:

  • Python 3.7 या इसके बाद का वर्शन
  • pip पैकेज मैनेजमेंट टूल.
  • Python 2.0 के लिए Google APIs क्लाइंट लाइब्रेरी की रिलीज़:
    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
  • requests एचटीटीपी लाइब्रेरी.
    pip install --upgrade requests

अगर Python और उससे जुड़ी माइग्रेशन गाइड को अपग्रेड नहीं किया जा सकता, तो Google API Python क्लाइंट लाइब्रेरी का रिलीज़ नोट देखें.

Ruby

इस दस्तावेज़ में दिए गए Ruby कोड सैंपल को चलाने के लिए, आपको इनकी ज़रूरत होगी:

  • Ruby 2.6 या इसके बाद का वर्शन
  • Ruby के लिए Google Auth Library:

    gem install googleauth
  • Drive और Calendar के Google API के लिए क्लाइंट लाइब्रेरी:

    gem install google-apis-drive_v3 google-apis-calendar_v3
  • Sinatra Ruby वेब ऐप्लिकेशन फ़्रेमवर्क.

    gem install sinatra

Node.js

इस दस्तावेज़ में दिए गए Node.js कोड सैंपल चलाने के लिए, आपको इनकी ज़रूरत होगी:

  • Node.js का मेंटेनेंस एलटीएस, ऐक्टिव एलटीएस या मौजूदा रिलीज़.
  • Google API Node.js क्लाइंट:

    npm install googleapis crypto express express-session

एचटीटीपी/आरईएसटी

OAuth 2.0 एंडपॉइंट को सीधे कॉल करने के लिए, आपको कोई लाइब्रेरी इंस्टॉल करने की ज़रूरत नहीं है.

OAuth 2.0 ऐक्सेस टोकन पाना

यहां बताया गया है कि आपका ऐप्लिकेशन, Google के OAuth 2.0 सर्वर के साथ कैसे इंटरैक्ट करता है, ताकि उपयोगकर्ता की ओर से एपीआई अनुरोध करने के लिए, उपयोगकर्ता की सहमति ली जा सके. आपके ऐप्लिकेशन के पास वह सहमति होनी चाहिए. इसके बाद ही, वह Google API के ऐसे अनुरोध को लागू कर सकता है जिसके लिए उपयोगकर्ता की अनुमति ज़रूरी है.

यहां दी गई सूची में, इन चरणों के बारे में खास जानकारी दी गई है:

  1. आपका ऐप्लिकेशन उन अनुमतियों की पहचान करता है जिनकी उसे ज़रूरत है.
  2. आपका ऐप्लिकेशन, उपयोगकर्ता को Google पर रीडायरेक्ट करता है. साथ ही, उन अनुमतियों की सूची भी भेजता है जिनके लिए अनुरोध किया गया है.
  3. उपयोगकर्ता यह तय करता है कि आपके ऐप्लिकेशन को अनुमतियां देनी हैं या नहीं.
  4. आपके ऐप्लिकेशन को पता चलता है कि उपयोगकर्ता ने क्या फ़ैसला लिया.
  5. अगर उपयोगकर्ता ने अनुरोध की गई अनुमतियां दी हैं, तो आपका ऐप्लिकेशन उपयोगकर्ता की ओर से एपीआई अनुरोध करने के लिए ज़रूरी टोकन हासिल करता है.

पहला चरण: अनुमति देने के पैरामीटर सेट करना

सबसे पहले, अनुमति देने का अनुरोध करें. इस अनुरोध से ऐसे पैरामीटर सेट होते हैं जो आपके ऐप्लिकेशन की पहचान करते हैं. साथ ही, उन अनुमतियों को तय करते हैं जिन्हें उपयोगकर्ता को आपके ऐप्लिकेशन को देने के लिए कहा जाएगा.

  • अगर OAuth 2.0 की मदद से पुष्टि करने और अनुमति देने के लिए, Google क्लाइंट लाइब्रेरी का इस्तेमाल किया जाता है, तो आपको एक ऐसा ऑब्जेक्ट बनाना और कॉन्फ़िगर करना होगा जो इन पैरामीटर को तय करता हो.
  • अगर Google OAuth 2.0 एंडपॉइंट को सीधे कॉल किया जाता है, तो आपको एक यूआरएल जनरेट करना होगा और उस यूआरएल पर पैरामीटर सेट करने होंगे.

यहां दिए गए टैब में, वेब सर्वर ऐप्लिकेशन के लिए अनुमति देने वाले पैरामीटर के बारे में बताया गया है. भाषा के हिसाब से दिए गए उदाहरणों से यह भी पता चलता है कि उन पैरामीटर को सेट करने वाले ऑब्जेक्ट को कॉन्फ़िगर करने के लिए, क्लाइंट लाइब्रेरी या अनुमति देने वाली लाइब्रेरी का इस्तेमाल कैसे किया जाता है:

PHP

यहां दिया गया कोड स्निपेट, एक Google\Client() ऑब्जेक्ट बनाता है. यह ऑब्जेक्ट, अनुमति के अनुरोध में पैरामीटर तय करता है.

वह ऑब्जेक्ट, आपके ऐप्लिकेशन की पहचान करने के लिए, आपकी client_secret.json फ़ाइल की जानकारी का इस्तेमाल करता है. (उस फ़ाइल के बारे में ज़्यादा जानने के लिए, अनुमति देने वाले क्रेडेंशियल बनाना देखें.) यह ऑब्जेक्ट उन स्कोप की भी पहचान करता है जिन्हें ऐक्सेस करने की अनुमति आपका ऐप्लिकेशन मांग रहा है. साथ ही, यह आपके ऐप्लिकेशन के ऑथराइज़ेशन एंडपॉइंट के यूआरएल की भी पहचान करता है. यह यूआरएल, Google के OAuth 2.0 सर्वर से मिलने वाले जवाब को मैनेज करेगा. आखिर में, कोड वैकल्पिक 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);

Python

यहां दिए गए कोड स्निपेट में, अनुमति का अनुरोध करने के लिए google-auth-oauthlib.flow मॉड्यूल का इस्तेमाल किया गया है.

यह कोड एक Flow ऑब्जेक्ट बनाता है, जो client_secret.json फ़ाइल में मौजूद जानकारी का इस्तेमाल करके आपके ऐप्लिकेशन की पहचान करता है. यह फ़ाइल, अनुमति देने वाले क्रेडेंशियल बनाने के बाद डाउनलोड की जाती है. यह ऑब्जेक्ट उन दायरों की भी पहचान करता है जिन्हें ऐक्सेस करने की अनुमति आपका ऐप्लिकेशन मांग रहा है. साथ ही, यह आपके ऐप्लिकेशन के ऑथराइज़ेशन एंडपॉइंट के यूआरएल की भी पहचान करता है. यह यूआरएल, Google के OAuth 2.0 सर्वर से मिलने वाले जवाब को मैनेज करेगा. आखिर में, कोड वैकल्पिक 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')

Ruby

अपने ऐप्लिकेशन में क्लाइंट ऑब्जेक्ट को कॉन्फ़िगर करने के लिए, client_secrets.json फ़ाइल का इस्तेमाल करें. क्लाइंट ऑब्जेक्ट को कॉन्फ़िगर करते समय, आपको वे स्कोप तय करने होते हैं जिन्हें ऐक्सेस करने की ज़रूरत आपके ऐप्लिकेशन को होती है. साथ ही, आपको अपने ऐप्लिकेशन के ऑथराइज़ेशन एंडपॉइंट का यूआरएल भी देना होता है. यह यूआरएल, 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 से जुड़ी कार्रवाइयां करने के लिए क्लाइंट ऑब्जेक्ट का इस्तेमाल करता है. जैसे, अनुमति के अनुरोध वाले यूआरएल जनरेट करना और एचटीटीपी अनुरोधों पर ऐक्सेस टोकन लागू करना.

Node.js

यहां दिया गया कोड स्निपेट, एक google.auth.OAuth2 ऑब्जेक्ट बनाता है. यह ऑब्जेक्ट, अनुमति के अनुरोध में पैरामीटर तय करता है.

वह ऑब्जेक्ट, आपके ऐप्लिकेशन की पहचान करने के लिए, आपकी client_secret.json फ़ाइल की जानकारी का इस्तेमाल करता है. ऐक्सेस टोकन पाने के लिए, उपयोगकर्ता से अनुमतियां मांगने के लिए, उसे सहमति वाले पेज पर रीडायरेक्ट करें. सहमति वाले पेज का यूआरएल बनाने के लिए:

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

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

// Access scopes for 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 सिर्फ़ पहली बार अनुमति मिलने पर ही मिलता है. ज़्यादा जानकारी के लिए यहां जाएं.

एचटीटीपी/आरईएसटी

Google का OAuth 2.0 एंडपॉइंट https://accounts.google.com/o/oauth2/v2/auth पर है. इस एंडपॉइंट को सिर्फ़ एचटीटीपीएस से ऐक्सेस किया जा सकता है. एचटीटीपी कनेक्शन अस्वीकार कर दिए जाते हैं.

Google का ऑथराइज़ेशन सर्वर, वेब सर्वर ऐप्लिकेशन के लिए इन क्वेरी स्ट्रिंग पैरामीटर के साथ काम करता है:

पैरामीटर
client_id ज़रूरी है

आपके ऐप्लिकेशन का क्लाइंट आईडी. यह वैल्यू, Cloud Console के क्लाइंट पेज में देखी जा सकती है.

redirect_uri ज़रूरी है

इससे यह तय होता है कि अनुमति देने की प्रोसेस पूरी होने के बाद, एपीआई सर्वर उपयोगकर्ता को कहां रीडायरेक्ट करेगा. यह वैल्यू, OAuth 2.0 क्लाइंट के लिए अनुमति वाले किसी एक रीडायरेक्ट यूआरआई से पूरी तरह मेल खानी चाहिए. इसे आपने अपने क्लाइंट के Cloud Console क्लाइंट पेज पर कॉन्फ़िगर किया है. अगर यह वैल्यू, दिए गए client_id के लिए अनुमति वाले रीडायरेक्ट यूआरआई से मैच नहीं होती है, तो आपको redirect_uri_mismatch गड़बड़ी का मैसेज मिलेगा.

ध्यान दें कि http या https स्कीम, केस, और ट्रेलिंग स्लैश ('/') सभी मैच होने चाहिए.

response_type ज़रूरी है

इससे यह तय होता है कि Google OAuth 2.0 एंडपॉइंट, ऑथराइज़ेशन कोड दिखाता है या नहीं.

वेब सर्वर ऐप्लिकेशन के लिए, पैरामीटर वैल्यू को code पर सेट करें.

scope ज़रूरी है

स्कोप की ऐसी सूची जिसमें हर स्कोप को स्पेस से अलग किया गया हो. इससे उन संसाधनों की पहचान की जाती है जिन्हें आपका ऐप्लिकेशन, उपयोगकर्ता की ओर से ऐक्सेस कर सकता है. इन वैल्यू से, सहमति वाली स्क्रीन को जानकारी मिलती है. Google इस स्क्रीन को उपयोगकर्ता को दिखाता है.

स्कोप की मदद से, आपका ऐप्लिकेशन सिर्फ़ उन संसाधनों को ऐक्सेस करने का अनुरोध कर सकता है जिनकी उसे ज़रूरत है. साथ ही, उपयोगकर्ता यह कंट्रोल कर सकते हैं कि वे आपके ऐप्लिकेशन को कितना ऐक्सेस दें. इसलिए, अनुरोध किए गए स्कोप की संख्या और उपयोगकर्ता की सहमति मिलने की संभावना के बीच, इन्वर्स रिलेशनशिप होता है.

हमारा सुझाव है कि जब भी संभव हो, आपका ऐप्लिकेशन संदर्भ के हिसाब से अनुमति के स्कोप का ऐक्सेस मांगे. इंक्रीमेंटल ऑथराइज़ेशन का इस्तेमाल करके, उपयोगकर्ता के डेटा को ऐक्सेस करने का अनुरोध करने पर, उपयोगकर्ताओं को यह समझने में मदद मिलती है कि आपके ऐप्लिकेशन को ऐक्सेस की ज़रूरत क्यों है.

access_type सुझाया गया

इससे पता चलता है कि जब उपयोगकर्ता ब्राउज़र पर मौजूद न हो, तब आपका ऐप्लिकेशन ऐक्सेस टोकन रीफ़्रेश कर सकता है या नहीं. पैरामीटर की मान्य वैल्यू online और offline हैं. इनमें से डिफ़ॉल्ट वैल्यू है.

अगर आपके ऐप्लिकेशन को ऐक्सेस टोकन रीफ़्रेश करने की ज़रूरत है, तो वैल्यू को offline पर सेट करें. ऐसा तब करें, जब उपयोगकर्ता ब्राउज़र पर मौजूद न हो. यह ऐक्सेस टोकन रीफ़्रेश करने का तरीका है. इसके बारे में इस दस्तावेज़ में आगे बताया गया है. यह वैल्यू, Google के ऑथराइज़ेशन सर्वर को निर्देश देती है कि जब आपका ऐप्लिकेशन पहली बार टोकन के लिए ऑथराइज़ेशन कोड को एक्सचेंज करे, तब वह रीफ़्रेश टोकन और ऐक्सेस टोकन दिखाए.

state सुझाया गया

यह किसी ऐसी स्ट्रिंग वैल्यू के बारे में बताता है जिसका इस्तेमाल आपका ऐप्लिकेशन, अनुमति के अनुरोध और अनुमति देने वाले सर्वर के जवाब के बीच की स्थिति को बनाए रखने के लिए करता है. जब उपयोगकर्ता आपके ऐप्लिकेशन के ऐक्सेस अनुरोध को स्वीकार या अस्वीकार कर देता है, तब सर्वर वही वैल्यू दिखाता है जो आपने redirect_uri के यूआरएल क्वेरी कॉम्पोनेंट (?) में name=value पेयर के तौर पर भेजी थी.

इस पैरामीटर का इस्तेमाल कई कामों के लिए किया जा सकता है. जैसे, उपयोगकर्ता को आपके ऐप्लिकेशन में सही संसाधन पर भेजना, नॉन्स भेजना, और किसी दूसरी साइट से किए गए फ़र्ज़ी अनुरोध को कम करना. आपके redirect_uri का अनुमान लगाया जा सकता है. इसलिए, state वैल्यू का इस्तेमाल करने से, आपको यह भरोसा हो सकता है कि आने वाला कनेक्शन, पुष्टि करने के अनुरोध का नतीजा है. अगर आपने कोई रैंडम स्ट्रिंग जनरेट की है या किसी कुकी के हैश को एन्कोड किया है या क्लाइंट की स्थिति को कैप्चर करने वाली कोई अन्य वैल्यू जनरेट की है, तो जवाब की पुष्टि की जा सकती है. इससे यह भी पक्का किया जा सकता है कि अनुरोध और जवाब एक ही ब्राउज़र से जनरेट हुए हैं. इससे क्रॉस-साइट अनुरोध फ़ॉर्जरी जैसे हमलों से सुरक्षा मिलती है. state टोकन बनाने और उसकी पुष्टि करने का उदाहरण देखने के लिए, OpenID Connect दस्तावेज़ देखें.

include_granted_scopes ज़रूरी नहीं

इससे ऐप्लिकेशन, ज़रूरत के मुताबिक ज़्यादा स्कोप का ऐक्सेस पाने के लिए, इंक्रीमेंटल ऑथराइज़ेशन का इस्तेमाल कर सकते हैं. अगर इस पैरामीटर की वैल्यू को true पर सेट किया जाता है और अनुमति का अनुरोध स्वीकार कर लिया जाता है, तो नए ऐक्सेस टोकन में वे सभी स्कोप भी शामिल होंगे जिनके लिए उपयोगकर्ता ने पहले ऐप्लिकेशन को ऐक्सेस दिया था. उदाहरणों के लिए, इंक्रीमेंटल ऑथराइज़ेशन सेक्शन देखें.

login_hint ज़रूरी नहीं

अगर आपके ऐप्लिकेशन को पता है कि कौनसा उपयोगकर्ता पुष्टि करने की कोशिश कर रहा है, तो वह इस पैरामीटर का इस्तेमाल करके, Google के ऑथेंटिकेशन सर्वर को हिंट दे सकता है. सर्वर, लॉगिन की प्रोसेस को आसान बनाने के लिए हिंट का इस्तेमाल करता है. इसके लिए, वह साइन-इन फ़ॉर्म में ईमेल फ़ील्ड को पहले से भर देता है या सही मल्टी-लॉगिन सेशन चुनता है.

पैरामीटर वैल्यू को किसी ईमेल पते या sub आइडेंटिफ़ायर पर सेट करें. यह उपयोगकर्ता के Google आईडी के बराबर होता है.

prompt ज़रूरी नहीं

उपयोगकर्ता को दिखाने के लिए, स्पेस से अलग किए गए और केस-सेंसिटिव (बड़े और छोटे अक्षरों में अंतर) प्रॉम्प्ट की सूची. अगर आपने यह पैरामीटर तय नहीं किया है, तो उपयोगकर्ता को सिर्फ़ तब सूचना दी जाएगी, जब आपका प्रोजेक्ट पहली बार ऐक्सेस का अनुरोध करेगा. ज़्यादा जानकारी के लिए, फिर से सहमति देने के लिए कहना देखें.

इन वैल्यू का इस्तेमाल किया जा सकता है:

none पुष्टि करने या ऐसी स्क्रीन जहां OAuth के लिए सहमति दी जाती है, ऐसी कोई भी स्क्रीन न दिखाएं. इसे अन्य वैल्यू के साथ नहीं दिया जाना चाहिए.
consent उपयोगकर्ता से सहमति देने के लिए कहें.
select_account उपयोगकर्ता को कोई खाता चुनने के लिए कहें.

दूसरा चरण: Google के OAuth 2.0 सर्वर पर रीडायरेक्ट करना

उपयोगकर्ता को Google के OAuth 2.0 सर्वर पर रीडायरेक्ट करें, ताकि पुष्टि करने और अनुमति देने की प्रोसेस शुरू की जा सके. आम तौर पर, ऐसा तब होता है, जब आपके ऐप्लिकेशन को पहली बार उपयोगकर्ता के डेटा को ऐक्सेस करने की ज़रूरत होती है. इंक्रीमेंटल ऑथराइज़ेशन के मामले में, यह चरण तब भी होता है, जब आपके ऐप्लिकेशन को पहली बार उन अतिरिक्त संसाधनों को ऐक्सेस करने की ज़रूरत होती है जिन्हें ऐक्सेस करने की अनुमति उसके पास नहीं होती.

PHP

  1. Google के OAuth 2.0 सर्वर से ऐक्सेस का अनुरोध करने के लिए, एक यूआरएल जनरेट करें:
    $auth_url = $client->createAuthUrl();
  2. उपयोगकर्ता को $auth_url पर रीडायरेक्ट करें:
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

इस उदाहरण में, Flask वेब ऐप्लिकेशन फ़्रेमवर्क का इस्तेमाल करके, उपयोगकर्ता को अनुमति देने वाले यूआरएल पर रीडायरेक्ट करने का तरीका बताया गया है:

return flask.redirect(authorization_url)

Ruby

  1. Google के OAuth 2.0 सर्वर से ऐक्सेस का अनुरोध करने के लिए, एक यूआरएल जनरेट करें:
    auth_uri = authorizer.get_authorization_url(request: request)
  2. उपयोगकर्ता को auth_uri पर रीडायरेक्ट करें.

Node.js

  1. Google के OAuth 2.0 सर्वर से ऐक्सेस का अनुरोध करने के लिए, पहले चरण में जनरेट किए गए यूआरएल authorizationUrl generateAuthUrl तरीके का इस्तेमाल करें.
  2. उपयोगकर्ता को authorizationUrl पर रीडायरेक्ट करें.
    res.redirect(authorizationUrl);

एचटीटीपी/आरईएसटी

Google के अनुमति देने वाले सर्वर पर रीडायरेक्ट करने का सैंपल

यहां एक यूआरएल का उदाहरण दिया गया है. इसमें लाइन ब्रेक और स्पेस का इस्तेमाल किया गया है, ताकि इसे आसानी से पढ़ा जा सके.

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//developers.google.com/oauthplayground&
 client_id=client_id

अनुरोध का यूआरएल बनाने के बाद, उपयोगकर्ता को उस पर रीडायरेक्ट करें.

Google का OAuth 2.0 सर्वर, उपयोगकर्ता की पुष्टि करता है. साथ ही, आपके ऐप्लिकेशन के लिए उपयोगकर्ता से सहमति लेता है, ताकि वह अनुरोध किए गए दायरों को ऐक्सेस कर सके. आपके बताए गए रीडायरेक्ट यूआरएल का इस्तेमाल करके, जवाब आपके ऐप्लिकेशन को वापस भेज दिया जाता है.

तीसरा चरण: Google, उपयोगकर्ता से सहमति मांगता है

इस चरण में, उपयोगकर्ता यह तय करता है कि आपके ऐप्लिकेशन को अनुरोध किया गया ऐक्सेस देना है या नहीं. इस चरण में, Google सहमति वाली एक विंडो दिखाता है. इसमें आपके ऐप्लिकेशन का नाम और Google API की उन सेवाओं के नाम दिखते हैं जिन्हें ऐक्सेस करने की अनुमति मांगी जा रही है. इसके लिए, उपयोगकर्ता के क्रेडेंशियल और ऐक्सेस के स्कोप की खास जानकारी मांगी जाती है. इसके बाद, उपयोगकर्ता आपके ऐप्लिकेशन के अनुरोध किए गए एक या उससे ज़्यादा स्कोप का ऐक्सेस देने के लिए सहमति दे सकता है या अनुरोध को अस्वीकार कर सकता है.

इस चरण में, आपके ऐप्लिकेशन को कुछ करने की ज़रूरत नहीं है. ऐसा इसलिए, क्योंकि यह Google के OAuth 2.0 सर्वर से जवाब मिलने का इंतज़ार करता है. इससे पता चलता है कि ऐक्सेस दिया गया है या नहीं. इस जवाब के बारे में अगले चरण में बताया गया है.

गड़बड़ियां

Google के OAuth 2.0 ऑथराइज़ेशन एंडपॉइंट को किए गए अनुरोधों में, उपयोगकर्ताओं को गड़बड़ी के मैसेज दिख सकते हैं. ऐसा तब हो सकता है, जब पुष्टि करने और अनुमति देने के फ़्लो उम्मीद के मुताबिक काम न करें. गड़बड़ी के सामान्य कोड और उन्हें ठीक करने के लिए सुझाए गए तरीके:

admin_policy_enforced

Google Workspace एडमिन की नीतियों की वजह से, Google खाते से अनुरोध किए गए एक या उससे ज़्यादा स्कोप को अनुमति नहीं दी जा सकती. Google Workspace एडमिन के लिए उपलब्ध सहायता लेख तीसरे पक्ष और आपके डोमेन के मालिकाना हक वाले किन ऐप्लिकेशन से, Google Workspace का डेटा ऐक्सेस किया जा सकता है, इसे कंट्रोल करें देखें. इससे आपको इस बारे में ज़्यादा जानकारी मिलेगी कि कोई एडमिन, सभी दायरों या संवेदनशील और प्रतिबंधित दायरों के ऐक्सेस पर तब तक पाबंदी कैसे लगा सकता है, जब तक आपके OAuth क्लाइंट आईडी को साफ़ तौर पर ऐक्सेस नहीं दिया जाता.

disallowed_useragent

ऑथराइज़ेशन एंडपॉइंट, एम्बेड किए गए ऐसे उपयोगकर्ता एजेंट में दिखता है जिसकी अनुमति Google की OAuth 2.0 नीतियों के तहत नहीं है.

iOS और macOS डेवलपर को WKWebView में अनुमति के अनुरोध खोलते समय यह गड़बड़ी दिख सकती है. इसके बजाय, डेवलपर को iOS लाइब्रेरी का इस्तेमाल करना चाहिए. जैसे, iOS के लिए Google साइन-इन या OpenID Foundation का iOS के लिए AppAuth.

वेब डेवलपर को यह गड़बड़ी तब दिख सकती है, जब कोई iOS या macOS ऐप्लिकेशन, एम्बेड किए गए उपयोगकर्ता एजेंट में कोई सामान्य वेब लिंक खोलता है और कोई उपयोगकर्ता आपकी साइट से Google के OAuth 2.0 ऑथराइज़ेशन एंडपॉइंट पर जाता है. डेवलपर को सामान्य लिंक, ऑपरेटिंग सिस्टम के डिफ़ॉल्ट लिंक हैंडलर में खोलने की अनुमति देनी चाहिए. इसमें यूनिवर्सल लिंक हैंडलर या डिफ़ॉल्ट ब्राउज़र ऐप्लिकेशन, दोनों शामिल हैं. SFSafariViewController लाइब्रेरी भी एक विकल्प है.

org_internal

अनुरोध में मौजूद OAuth क्लाइंट आईडी, किसी ऐसे प्रोजेक्ट का हिस्सा है जो किसी खास Google Cloud संगठन में मौजूद Google खातों के ऐक्सेस को सीमित करता है. कॉन्फ़िगरेशन के इस विकल्प के बारे में ज़्यादा जानने के लिए, 'OAuth के लिए सहमति वाली स्क्रीन सेट अप करना' सहायता लेख में उपयोगकर्ता टाइप सेक्शन देखें.

invalid_client

OAuth क्लाइंट सीक्रेट गलत है. OAuth क्लाइंट कॉन्फ़िगरेशन की समीक्षा करें. इसमें इस अनुरोध के लिए इस्तेमाल किया गया क्लाइंट आईडी और सीक्रेट शामिल है.

deleted_client

अनुरोध करने के लिए इस्तेमाल किए जा रहे OAuth क्लाइंट को मिटा दिया गया है. डेटा को मैन्युअल तरीके से मिटाया जा सकता है. इसके अलावा, इस्तेमाल नहीं किए जा रहे क्लाइंट के मामले में, डेटा अपने-आप मिट सकता है. मिटाए गए क्लाइंट को 30 दिनों के अंदर वापस लाया जा सकता है. ज़्यादा जानें .

invalid_grant

ऐक्सेस टोकन को रीफ़्रेश करते समय या इंक्रीमेंटल ऑथराइज़ेशन का इस्तेमाल करते समय, हो सकता है कि टोकन की समयसीमा खत्म हो गई हो या उसे अमान्य कर दिया गया हो. उपयोगकर्ता की फिर से पुष्टि करें और नए टोकन पाने के लिए, उपयोगकर्ता की सहमति लें. अगर आपको यह गड़बड़ी अब भी दिख रही है, तो पक्का करें कि आपका ऐप्लिकेशन सही तरीके से कॉन्फ़िगर किया गया हो. साथ ही, यह भी पक्का करें कि आपने अपने अनुरोध में सही टोकन और पैरामीटर का इस्तेमाल किया हो. ऐसा न होने पर, हो सकता है कि उपयोगकर्ता खाता मिटा दिया गया हो या बंद कर दिया गया हो.

redirect_uri_mismatch

अनुमति के अनुरोध में पास किया गया redirect_uri, OAuth क्लाइंट आईडी के लिए अनुमति वाले रीडायरेक्ट यूआरआई से मेल नहीं खाता. Google Cloud Console के क्लाइंट पेज पर जाकर, अनुमति वाले रीडायरेक्ट यूआरआई देखें.

redirect_uri पैरामीटर, OAuth आउट-ऑफ़-बैंड (ओओबी) फ़्लो को रेफ़र कर सकता है. इसे बंद कर दिया गया है और अब यह काम नहीं करता. अपने इंटिग्रेशन को अपडेट करने के लिए, माइग्रेट करने से जुड़ी गाइड देखें.

invalid_request

आपके अनुरोध में कोई गड़बड़ी थी. ऐसा कई वजहों से हो सकता है:

  • अनुरोध को सही तरीके से फ़ॉर्मैट नहीं किया गया था
  • अनुरोध में ज़रूरी पैरामीटर मौजूद नहीं थे
  • अनुरोध में, अनुमति देने के लिए किसी ऐसे तरीके का इस्तेमाल किया गया है जो Google के साथ काम नहीं करता. पुष्टि करें कि आपके OAuth इंटिग्रेशन में, इंटिग्रेशन के लिए सुझाए गए तरीके का इस्तेमाल किया गया हो

चौथा चरण: OAuth 2.0 सर्वर से मिले जवाब को मैनेज करना

OAuth 2.0 सर्वर, आपके ऐप्लिकेशन के ऐक्सेस के अनुरोध का जवाब देता है. इसके लिए, वह अनुरोध में दिए गए यूआरएल का इस्तेमाल करता है.

अगर उपयोगकर्ता ऐक्सेस के अनुरोध को स्वीकार कर लेता है, तो जवाब में एक ऑथराइज़ेशन कोड शामिल होता है. अगर उपयोगकर्ता अनुरोध को स्वीकार नहीं करता है, तो जवाब में गड़बड़ी का मैसेज दिखता है. वेब सर्वर को मिलने वाला अनुमति कोड या गड़बड़ी का मैसेज, क्वेरी स्ट्रिंग पर दिखता है. इसके उदाहरण यहां दिए गए हैं:

गड़बड़ी का जवाब:

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

ऑथराइज़ेशन कोड का रिस्पॉन्स:

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

OAuth 2.0 सर्वर के जवाब का सैंपल

इस फ़्लो को टेस्ट करने के लिए, यहां दिए गए सैंपल यूआरएल पर क्लिक करें. यह यूआरएल, आपके Google Drive में मौजूद फ़ाइलों के मेटाडेटा को देखने के लिए रीड-ओनली ऐक्सेस और आपके Google 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//developers.google.com/oauthplayground&
 client_id=client_id

OAuth 2.0 फ़्लो पूरा होने के बाद, आपका ब्राउज़र आपको OAuth 2.0 Playground पर रीडायरेक्ट कर देता है. यह OAuth फ़्लो की जांच करने वाला टूल है. आपको दिखेगा कि OAuth 2.0 Playground ने ऑथराइज़ेशन कोड को अपने-आप कैप्चर कर लिया है.

पांचवां चरण: रीफ़्रेश और ऐक्सेस टोकन के लिए, ऑथराइज़ेशन कोड को एक्सचेंज करना

वेब सर्वर को ऑथराइज़ेशन कोड मिलने के बाद, वह ऑथराइज़ेशन कोड को ऐक्सेस टोकन से बदल सकता है.

PHP

ऑथराइज़ेशन कोड को ऐक्सेस टोकन से बदलने के लिए, fetchAccessTokenWithAuthCode तरीके का इस्तेमाल करें:

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

Python

अपने कॉलबैक पेज पर, अनुमति देने वाले सर्वर के जवाब की पुष्टि करने के लिए, google-auth लाइब्रेरी का इस्तेमाल करें. इसके बाद, उस जवाब में मिले ऑथराइज़ेशन कोड को ऐक्सेस टोकन में बदलने के लिए, flow.fetch_token तरीके का इस्तेमाल करें:

state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/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 browser session storage, but for security: client_id, client_secret,
# and token_uri are instead stored only on the backend server.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'granted_scopes': credentials.granted_scopes}

Ruby

अपने कॉलबैक पेज पर, अनुमति देने वाले सर्वर के जवाब की पुष्टि करने के लिए, googleauth लाइब्रेरी का इस्तेमाल करें. ऑथराइज़ेशन कोड को सेव करने के लिए, authorizer.handle_auth_callback_deferred तरीके का इस्तेमाल करें. इसके बाद, उस यूआरएल पर वापस रीडायरेक्ट करें जिसने मूल रूप से अनुमति का अनुरोध किया था. इससे, कोड के एक्सचेंज में देरी होती है. ऐसा इसलिए होता है, क्योंकि नतीजों को उपयोगकर्ता के सेशन में कुछ समय के लिए सेव कर लिया जाता है.

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

Node.js

ऑथराइज़ेशन कोड को ऐक्सेस टोकन से बदलने के लिए, getToken तरीके का इस्तेमाल करें:

const url = require('url');

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

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

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

एचटीटीपी/आरईएसटी

ऐक्सेस टोकन के लिए ऑथराइज़ेशन कोड को एक्सचेंज करने के लिए, https://oauth2.googleapis.com/token एंडपॉइंट को कॉल करें और ये पैरामीटर सेट करें:

फ़ील्ड
client_id Cloud Console के क्लाइंट पेज से मिला क्लाइंट आईडी.
client_secret ज़रूरी नहीं

Cloud Console के क्लाइंट पेज से मिला क्लाइंट सीक्रेट.

code शुरुआती अनुरोध से मिला ऑथराइज़ेशन कोड.
grant_type OAuth 2.0 की खास जानकारी में बताए गए तरीके के मुताबिक, इस फ़ील्ड की वैल्यू authorization_code पर सेट होनी चाहिए.
redirect_uri दिए गए client_id के लिए, Cloud Console के क्लाइंट पेज पर आपके प्रोजेक्ट के लिए लिस्ट किए गए रीडायरेक्ट यूआरआई में से कोई एक.

डीपीओपी का इस्तेमाल करना ज़रूरी नहीं है. हालांकि, बेहतर सुरक्षा के लिए इसका सुझाव दिया जाता है. डीपीओपी की सुरक्षा, निजी पासकोड को किसी एक डिवाइस तक सीमित रखने पर निर्भर करती है. हमारा सुझाव है कि इसे इस तरह से सेव करें कि इसे डिवाइस से कॉपी न किया जा सके. उदाहरण के लिए, टीपीएम, सिक्योर एन्क्लेव या हार्डवेयर से सुरक्षित अन्य कीस्टोर का इस्तेमाल करके. डीपीओपी का इस्तेमाल करने के लिए, आपके ऐप्लिकेशन को टोकन एंडपॉइंट पर किए जाने वाले हर अनुरोध के लिए, एक नया और यूनीक डीपीओपी प्रूफ़ JWT जनरेट करना होगा. साथ ही, उसे एचटीटीपी अनुरोध के हेडर के तौर पर जोड़ना होगा.

हेडर ज़रूरी है ब्यौरा
DPoP वैकल्पिक डीपीओपी प्रूफ़ एक जेडब्ल्यूटी है, जिससे निजी पासकोड के मालिकाना हक की पुष्टि होती है. यह एक हेडर है, न कि पैरामीटर. अगर टोकन दिए जाते हैं, तो वे इस कुंजी से जुड़े होते हैं. हर अनुरोध के लिए एक नया और यूनीक सबूत जनरेट किया जाना चाहिए. साथ ही, इसमें htm (एचटीटीपी तरीका) और htu (एचटीटीपी यूआरआई) दावे शामिल होने चाहिए, जो अनुरोध से मेल खाते हों.

यहां दिए गए स्निपेट में, अनुरोध का एक सैंपल दिखाया गया है:

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

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

DPoP प्रूफ़ बनाना

यहां बताया गया है कि कमांड लाइन से OpenSSL का इस्तेमाल करके, डीपीओपी प्रूफ़ कैसे बनाया जाता है:

  1. ईसी P-256 कुंजी का जोड़ा जनरेट करें:
    openssl ecparam -name prime256v1 -genkey -noout -out dpop_private.pem
    openssl ec -in dpop_private.pem -pubout -out dpop_public.pem
  2. डीपीओपी हेडर बनाएं:

    हेडर में typ, alg, और jwk (सार्वजनिक पासकोड) के दावे शामिल होने चाहिए. x और y वैल्यू, आपकी ईसी सार्वजनिक कुंजी के Base64Url-कोड में बदले गए निर्देशांक हैं. इस JSON को Base64Url कोड में बदलें:

    {
      "typ":"dpop+jwt",
      "alg":"ES256",
      "jwk": {
        "kty":"EC",
        "x":"YOUR_PUBLIC_KEY_X",
        "y":"YOUR_PUBLIC_KEY_Y",
        "crv":"P-256"
      }
    }
  3. डीपीओपी पेलोड बनाएं:

    पेलोड में jti (अनुरोध के लिए यूनीक आइडेंटिफ़ायर), htm (एचटीटीपी तरीका, जैसे कि POST), htu (एचटीटीपी यूआरआई, जैसे कि https://oauth2.googleapis.com/token), और iat (जारी करने का समय) शामिल होना चाहिए. अगर आपको पिछले अनुरोध के जवाब में, DPoP-Nonce हेडर में सर्वर से कोई नॉन्स मिला है, तो आपको उस नॉन्स वैल्यू को nonce दावे में शामिल करना होगा. ऑथराइज़ेशन कोड एक्सचेंज के लिए, नॉन्स क्लेम करना ज़रूरी नहीं है. इसका इस्तेमाल सिर्फ़ तब किया जाता है, जब DPoP-Nonce हेडर पहले मिल चुका हो. इस JSON को Base64Url कोड में बदलें:

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

    jti की वैल्यू, एक्सचेंज के टाइप पर निर्भर करती है:

    • ऑथराइज़ेशन कोड एक्सचेंज के लिए, jti, ऑथराइज़ेशन कोड का Base64Url-कोड में बदला गया SHA256 हैश होना चाहिए: "jti":"BASE64URL(SHA256(AUTHORIZATION_CODE))".
    • रिफ़्रेश टोकन एक्सचेंज के लिए, jti हर अनुरोध के लिए एक यूनीक आइडेंटिफ़ायर होना चाहिए: "jti":"YOUR_UNIQUE_PER_REQUEST_IDENTIFIER".
  4. सबूत पर हस्ताक्षर करना:

    एन्कोड किए गए हेडर और पेलोड को पीरियड (.) के साथ जोड़ें. इसके बाद, ES256 का इस्तेमाल करके, अपने निजी पासकोड से नतीजे पर हस्ताक्षर करें. ध्यान दें कि JWS के लिए, हस्ताक्षर को रॉ R | S कॉनकैटेनेटेड फ़ॉर्मैट (P-256 के लिए 64 बाइट) में होना चाहिए. अगर OpenSSL का सीधे तौर पर इस्तेमाल किया जा रहा है, तो आपको डिफ़ॉल्ट ASN.1 DER-एन्कोड किए गए सिग्नेचर को इस रॉ फ़ॉर्मैट में बदलना होगा.

सफल एक्सचेंज की जानकारी, टोकन वाले 200 OK रिस्पॉन्स से मिलती है. अगर एक्सचेंज के दौरान मान्य डीपीओपी प्रूफ़ का इस्तेमाल किया जाता है, तो Google जो रीफ़्रेश टोकन दिखाएगा वह आपकी कुंजी से डीपीओपी-बाउंड होगा. हालांकि, ऐक्सेस टोकन डीपीओपी बाउंड नहीं होंगे. ऐक्सेस टोकन में DPoP के बजाय Bearer की token_type बनी रहेगी. इसके अलावा, Google जवाब में DPoP-Nonce एचटीटीपी हेडर दिखाता है. आपके क्लाइंट को इस नॉन्स को कैश मेमोरी में सेव करना होगा. साथ ही, इसे बाद के अनुरोधों में डीपीओपी प्रूफ़ के nonce दावे में शामिल करना होगा. जैसे, रीफ़्रेश टोकन को नए ऐक्सेस टोकन से बदलते समय या डीपीओपी से सुरक्षित एपीआई को कॉल करते समय. पहले से जारी किए गए इस नॉन्स का इस्तेमाल करके, अपने अगले अनुरोध पर दोतरफ़ा यात्रा की गड़बड़ी (use_dpop_nonce) से बचा जा सकता है.

DPoP से बाउंड किए गए रीफ़्रेश टोकन के साथ किए गए टोकन एक्सचेंज के अनुरोधों के लिए, DPoP के सबूत शामिल किए जाने चाहिए.

एक्सचेंज पूरा न होने की समस्या तब आती है, जब DPoP हेडर मौजूद न हो, अमान्य हो या सबूत के तौर पर टोकन से बाउंड की गई कुंजी के बजाय किसी दूसरी कुंजी का इस्तेमाल किया गया हो. इन मामलों में, सर्वर 400 Bad Request गड़बड़ी दिखाता है. अगर डीपीओपी प्रूफ़ में htm या htu के दावे मेल नहीं खाते हैं, iat की समयसीमा खत्म हो गई है, jti का फिर से इस्तेमाल किया गया है या हस्ताक्षर अमान्य है, तो Google invalid_dpop_proof गड़बड़ी का कोड दिखाता है. अगर डीपीओपी नॉन्स की ज़रूरत है, जैसे कि रीफ़्रेश टोकन एक्सचेंज के दौरान, और डीपीओपी प्रूफ़ में nonce दावा मौजूद नहीं है या नॉन्स की वैल्यू सर्वर के लिए स्वीकार नहीं की जा सकती (उदाहरण के लिए, इसकी समयसीमा खत्म हो गई है, पहले ही इस्तेमाल की जा चुकी है या गलत है), तो Google use_dpop_nonce गड़बड़ी कोड के साथ-साथ DPoP-Nonce एचटीटीपी हेडर दिखाता है. इसमें एक नया नॉन्स होता है, जिसका इस्तेमाल बाद के अनुरोध में किया जा सकता है. अन्य गड़बड़ियों के लिए, invalid_grant दिख सकता है.

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 होती है, भले ही डीपीओपी का इस्तेमाल किया गया हो.

यहां दिए गए स्निपेट में, डीपीओपी का इस्तेमाल करने पर मिलने वाले रिस्पॉन्स हेडर और मुख्य हिस्से का सैंपल दिखाया गया है:

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

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

गड़बड़ियां

ऐक्सेस टोकन के लिए ऑथराइज़ेशन कोड को एक्सचेंज करते समय, आपको उम्मीद के मुताबिक जवाब के बजाय यह गड़बड़ी दिख सकती है. इस सेक्शन में, गड़बड़ी के सामान्य कोड और उन्हें ठीक करने के सुझाव दिए गए हैं.

invalid_grant

दिया गया ऑथराइज़ेशन कोड अमान्य है या उसका फ़ॉर्मैट गलत है. OAuth की प्रोसेस को रीस्टार्ट करके नए कोड का अनुरोध करें, ताकि उपयोगकर्ता से फिर से सहमति मांगी जा सके.

छठा चरण: यह देखना कि उपयोगकर्ताओं ने किन दायरों को ऐक्सेस करने की अनुमति दी है

एक से ज़्यादा अनुमतियों (स्कोप) का अनुरोध करने पर, हो सकता है कि उपयोगकर्ता आपके ऐप्लिकेशन को उन सभी अनुमतियों का ऐक्सेस न दें. आपके ऐप्लिकेशन को यह पुष्टि करनी होगी कि उसे असल में कौनसे स्कोप दिए गए हैं. साथ ही, उसे उन स्थितियों को भी बेहतर तरीके से मैनेज करना होगा जिनमें कुछ अनुमतियां नहीं दी गई हैं. आम तौर पर, ऐसा उन सुविधाओं को बंद करके किया जाता है जो अनुमति न दिए गए स्कोप पर निर्भर करती हैं.

हालांकि, इसके कुछ अपवाद हैं. Google Workspace Enterprise के ऐसे ऐप्लिकेशन जिनके पास डोमेन-वाइड डेलिगेशन ऑफ़ अथॉरिटी है या जिन्हें भरोसेमंद के तौर पर मार्क किया गया है वे अलग-अलग अनुमतियों के लिए सहमति देने वाली स्क्रीन को बायपास कर देते हैं. इन ऐप्लिकेशन के लिए, उपयोगकर्ताओं को अलग-अलग अनुमतियों के लिए सहमति देने वाली स्क्रीन नहीं दिखेगी. इसके बजाय, आपके ऐप्लिकेशन को अनुरोध किए गए सभी स्कोप का ऐक्सेस मिलेगा या किसी का भी नहीं.

ज़्यादा जानकारी के लिए, अलग-अलग अनुमतियों को मैनेज करने का तरीका देखें.

PHP

उपयोगकर्ता ने किन दायरों को ऐक्सेस करने की अनुमति दी है, यह देखने के लिए getGrantedScope() तरीके का इस्तेमाल करें:

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

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

Python

दिखाए गए credentials ऑब्जेक्ट में granted_scopes प्रॉपर्टी होती है. यह उन स्कोप की सूची होती है जिन्हें उपयोगकर्ता ने आपके ऐप्लिकेशन को अनुमति दी है.

credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    '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

Ruby

एक साथ कई स्कोप का अनुरोध करते समय, देखें कि credentials ऑब्जेक्ट की scope प्रॉपर्टी के ज़रिए कौनसे स्कोप दिए गए हैं.

# 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

एक साथ कई स्कोप का अनुरोध करते समय, देखें कि tokens ऑब्जेक्ट की scope प्रॉपर्टी के ज़रिए कौनसे स्कोप दिए गए हैं.

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

एचटीटीपी/आरईएसटी

यह देखने के लिए कि उपयोगकर्ता ने आपके ऐप्लिकेशन को किसी खास दायरे का ऐक्सेस दिया है या नहीं, ऐक्सेस टोकन के जवाब में 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

Google API को कॉल करने के लिए, ऐक्सेस टोकन का इस्तेमाल करें. इसके लिए, यह तरीका अपनाएं:

  1. अगर आपको किसी नए Google\Client ऑब्जेक्ट पर ऐक्सेस टोकन लागू करना है — उदाहरण के लिए, अगर आपने ऐक्सेस टोकन को उपयोगकर्ता सेशन में सेव किया है — तो setAccessToken तरीके का इस्तेमाल करें:
    $client->setAccessToken($access_token);
  2. जिस एपीआई को कॉल करना है उसके लिए एक सेवा ऑब्जेक्ट बनाएं. सेवा ऑब्जेक्ट बनाने के लिए, आपको उस एपीआई के कंस्ट्रक्टर को अनुमति वाला Google\Client ऑब्जेक्ट देना होगा जिसे आपको कॉल करना है. उदाहरण के लिए, Drive API को कॉल करने के लिए:
    $drive = new Google\Service\Drive($client);
  3. सेवा ऑब्जेक्ट से मिले इंटरफ़ेस का इस्तेमाल करके, एपीआई सेवा को अनुरोध भेजें. उदाहरण के लिए, पुष्टि किए गए उपयोगकर्ता के Google Drive में मौजूद फ़ाइलों की सूची बनाने के लिए:
    $files = $drive->files->listFiles(array());

Python

ऐक्सेस टोकन मिलने के बाद, आपका ऐप्लिकेशन उस टोकन का इस्तेमाल करके, किसी उपयोगकर्ता खाते या सेवा खाते की ओर से एपीआई अनुरोधों को अनुमति दे सकता है. जिस एपीआई को कॉल करना है उसके लिए सेवा ऑब्जेक्ट बनाने के लिए, उपयोगकर्ता के हिसाब से अनुमति देने वाले क्रेडेंशियल का इस्तेमाल करें. इसके बाद, उस ऑब्जेक्ट का इस्तेमाल करके, अनुमति वाले एपीआई अनुरोध करें.

  1. जिस एपीआई को कॉल करना है उसके लिए एक सेवा ऑब्जेक्ट बनाएं. सेवा ऑब्जेक्ट बनाने के लिए, googleapiclient.discovery लाइब्रेरी के build तरीके को कॉल करें. इसके लिए, एपीआई का नाम और वर्शन के साथ-साथ उपयोगकर्ता के क्रेडेंशियल का इस्तेमाल करें: उदाहरण के लिए, Drive API के वर्शन 3 को कॉल करने के लिए:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. सेवा ऑब्जेक्ट से मिले इंटरफ़ेस का इस्तेमाल करके, एपीआई सेवा को अनुरोध भेजें. उदाहरण के लिए, पुष्टि किए गए उपयोगकर्ता के Google Drive में मौजूद फ़ाइलों की सूची बनाने के लिए:
    files = drive.files().list().execute()

Ruby

ऐक्सेस टोकन मिलने के बाद, आपका ऐप्लिकेशन उस टोकन का इस्तेमाल करके, किसी उपयोगकर्ता खाते या सेवा खाते की ओर से एपीआई अनुरोध कर सकता है. जिस एपीआई को कॉल करना है उसके लिए सेवा ऑब्जेक्ट बनाने के लिए, उपयोगकर्ता के हिसाब से अनुमति देने वाले क्रेडेंशियल का इस्तेमाल करें. इसके बाद, उस ऑब्जेक्ट का इस्तेमाल करके, अनुमति वाले एपीआई अनुरोध करें.

  1. जिस एपीआई को कॉल करना है उसके लिए एक सेवा ऑब्जेक्ट बनाएं. उदाहरण के लिए, Drive API के वर्शन 3 को कॉल करने के लिए:
    drive = Google::Apis::DriveV3::DriveService.new
  2. सेवा पर क्रेडेंशियल सेट करें:
    drive.authorization = credentials
  3. सेवा ऑब्जेक्ट से मिले इंटरफ़ेस का इस्तेमाल करके, एपीआई सेवा को अनुरोध भेजें. उदाहरण के लिए, पुष्टि किए गए उपयोगकर्ता के Google Drive में मौजूद फ़ाइलों की सूची बनाने के लिए:
    files = drive.list_files

इसके अलावा, किसी तरीके को options पैरामीटर देकर, हर तरीके के हिसाब से अनुमति दी जा सकती है:

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

Node.js

ऐक्सेस टोकन पाने और उसे OAuth2 ऑब्जेक्ट पर सेट करने के बाद, Google 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.');
  }
});

एचटीटीपी/आरईएसटी

ऐप्लिकेशन को ऐक्सेस टोकन मिलने के बाद, टोकन का इस्तेमाल करके किसी उपयोगकर्ता खाते की ओर से Google API को कॉल किया जा सकता है. हालांकि, इसके लिए ज़रूरी है कि एपीआई को ऐक्सेस करने के लिए ज़रूरी स्कोप को अनुमति दी गई हो. इसके लिए, एपीआई को भेजे जाने वाले अनुरोध में ऐक्सेस टोकन शामिल करें. इसके लिए, access_token क्वेरी पैरामीटर या Authorization एचटीटीपी हेडर Bearer वैल्यू शामिल करें. जब भी संभव हो, एचटीटीपी हेडर का इस्तेमाल करना बेहतर होता है. ऐसा इसलिए, क्योंकि क्वेरी स्ट्रिंग, सर्वर लॉग में दिखती हैं. ज़्यादातर मामलों में, Google API को कॉल सेट अप करने के लिए क्लाइंट लाइब्रेरी का इस्तेमाल किया जा सकता है. उदाहरण के लिए, Drive Files API को कॉल करते समय.

OAuth 2.0 Playground पर जाकर, Google के सभी एपीआई आज़माए जा सकते हैं और उनके दायरे देखे जा सकते हैं.

एचटीटीपी GET के उदाहरण

Authorization: Bearer एचटीटीपी हेडर का इस्तेमाल करके, drive.files एंडपॉइंट (Drive Files API) को किया गया कॉल कुछ ऐसा दिख सकता है. ध्यान दें कि आपको अपना ऐक्सेस टोकन डालना होगा:

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

यहां access_token क्वेरी स्ट्रिंग पैरामीटर का इस्तेमाल करके, पुष्टि किए गए उपयोगकर्ता के लिए उसी एपीआई को कॉल किया गया है:

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

curl के उदाहरण

curl कमांड-लाइन ऐप्लिकेशन की मदद से, इन कमांड को टेस्ट किया जा सकता है. यहां एक उदाहरण दिया गया है, जिसमें एचटीटीपी हेडर विकल्प का इस्तेमाल किया गया है. हमारा सुझाव है कि आप भी इसी विकल्प का इस्तेमाल करें:

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

इसके अलावा, क्वेरी स्ट्रिंग पैरामीटर का विकल्प:

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

पूरी तरह से तैयार उदाहरण

यहां दिए गए उदाहरण में, उपयोगकर्ता के Google Drive में मौजूद फ़ाइलों की JSON फ़ॉर्मैट वाली सूची को प्रिंट किया गया है. ऐसा तब किया गया है, जब उपयोगकर्ता ने अपनी पहचान की पुष्टि कर ली है और ऐप्लिकेशन को अपने Drive के मेटाडेटा को ऐक्सेस करने की अनुमति दे दी है.

PHP

इस उदाहरण को चलाने के लिए:

  1. API Console में, रीडायरेक्ट यूआरएल की सूची में लोकल मशीन का यूआरएल जोड़ें. उदाहरण के लिए, http://localhost:8080 जोड़ें.
  2. नई डायरेक्ट्री बनाएं और उस पर जाएं. उदाहरण के लिए:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. Composer का इस्तेमाल करके, PHP के लिए Google API क्लाइंट लाइब्रेरी इंस्टॉल करें:
    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'];
}
?>

Python

इस उदाहरण में, Flask फ़्रेमवर्क का इस्तेमाल किया गया है. यह http://localhost:8080 पर एक वेब ऐप्लिकेशन चलाता है, जिससे आपको OAuth 2.0 फ़्लो को टेस्ट करने की सुविधा मिलती है. उस यूआरएल पर जाने पर, आपको पांच लिंक दिखेंगे:

  • Drive API को कॉल करें: यह लिंक ऐसे पेज पर ले जाता है जो सैंपल एपीआई अनुरोध को लागू करने की कोशिश करता है. ऐसा तब होता है, जब उपयोगकर्ताओं ने अनुमति दी हो. ज़रूरत पड़ने पर, यह अनुमति देने की प्रोसेस शुरू करता है. कामयाब रहने पर, पेज पर एपीआई से मिली जानकारी दिखती है.
  • Calendar API को कॉल करने के लिए मॉक पेज: यह लिंक एक मॉक पेज पर ले जाता है. अगर उपयोगकर्ताओं ने अनुमति दी है, तो यह पेज Calendar API के अनुरोध का सैंपल लागू करने की कोशिश करता है. ज़रूरत पड़ने पर, यह अनुमति देने की प्रोसेस शुरू करता है. कामयाब रहने पर, पेज पर एपीआई से मिली जानकारी दिखती है.
  • पुष्टि करने के फ़्लो को सीधे तौर पर टेस्ट करें: यह लिंक, उपयोगकर्ता को अनुमति देने के फ़्लो पर भेजने की कोशिश करने वाले पेज पर ले जाता है. ऐप्लिकेशन, उपयोगकर्ता की ओर से अनुमति वाले एपीआई अनुरोध सबमिट करने की अनुमति मांगता है.
  • मौजूदा क्रेडेंशियल रद्द करें: यह लिंक उस पेज पर ले जाता है जो उपयोगकर्ता की ओर से ऐप्लिकेशन को पहले से दी गई अनुमतियों को रद्द करता है.
  • Flask सेशन के क्रेडेंशियल मिटाना: इस लिंक से, Flask सेशन में सेव किए गए अनुमति के क्रेडेंशियल मिट जाते हैं. इससे आपको यह देखने में मदद मिलती है कि अगर आपके ऐप्लिकेशन को पहले ही अनुमति दे चुका कोई उपयोगकर्ता, नए सेशन में एपीआई अनुरोध को लागू करने की कोशिश करता है, तो क्या होगा. इससे आपको यह भी पता चलता है कि अगर कोई उपयोगकर्ता आपके ऐप्लिकेशन को दी गई अनुमतियां वापस ले लेता है, तो आपके ऐप्लिकेशन को एपीआई से क्या जवाब मिलेगा. साथ ही, यह भी पता चलता है कि अगर आपका ऐप्लिकेशन, वापस लिए गए ऐक्सेस टोकन की मदद से किसी अनुरोध को अनुमति देने की कोशिश करता है, तो क्या होगा.
# -*- coding: utf-8 -*-

import os
import flask
import json
import requests

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

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

# The OAuth 2.0 access scope allows for access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/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 client secrets from the server-side file.
    with open(CLIENT_SECRETS_FILE, 'r') as f:
        client_config = json.load(f)['web']

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

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

    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.
    flask.session['credentials'] = credentials_to_dict(credentials)

    return flask.jsonify(**files)
  else:
    # User didn't authorize read-only Drive activity permission.
    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.')

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

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

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

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

  status_code = getattr(revoke, 'status_code')
  if status_code == 200:
    # Clear the user's session credentials after successful revocation
    if 'credentials' in flask.session:
        del flask.session['credentials']
        del flask.session['features']
    return('Credentials successfully revoked.' + print_index_table())
  else:
    return('An error occurred.' + print_index_table())

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

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

def 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="/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="/drive">Call Drive API directly</a></td>' +
          '<td> Use stored credentials to call the API, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' +
          '<tr><td><a href="/calendar">Call Calendar API directly</a></td>' +
          '<td> Use stored credentials to call the API, 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="/authorize">authorize</a> ' +
          '    again, you should go back to the auth flow.' +
          '</td></tr></table>')

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

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

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

Ruby

इस उदाहरण में, Sinatra फ़्रेमवर्क का इस्तेमाल किया गया है.

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

require 'google/apis/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. API Console में, रीडायरेक्ट यूआरएल की सूची में लोकल मशीन का यूआरएल जोड़ें. उदाहरण के लिए, http://localhost जोड़ें.
  2. पक्का करें कि आपके पास Node.js का मेंटेनेंस एलटीएस, ऐक्टिव एलटीएस या मौजूदा रिलीज़ इंस्टॉल हो.
  3. नई डायरेक्ट्री बनाएं और उस पर जाएं. उदाहरण के लिए:
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. npm का इस्तेमाल करके, Node.js के लिए Google API क्लाइंट लाइब्रेरी इंस्टॉल करें:
    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);

एचटीटीपी/आरईएसटी

Python के इस उदाहरण में, OAuth 2.0 वेब फ़्लो को दिखाने के लिए, Flask फ़्रेमवर्क और Requests लाइब्रेरी का इस्तेमाल किया गया है. हमारा सुझाव है कि इस फ़्लो के लिए, Python के लिए Google API की क्लाइंट लाइब्रेरी का इस्तेमाल करें. (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()

रीडायरेक्ट यूआरआई की पुष्टि करने के नियम

Google, रीडायरेक्ट यूआरआई के लिए पुष्टि करने के ये नियम लागू करता है, ताकि डेवलपर अपने ऐप्लिकेशन को सुरक्षित रख सकें. आपके रीडायरेक्ट यूआरआई को इन नियमों का पालन करना चाहिए. इन नियमों में इस्तेमाल किए गए डोमेन, होस्ट, पाथ, क्वेरी, स्कीम, और उपयोगकर्ता की जानकारी की परिभाषा के लिए, आरएफ़सी 3986 सेक्शन 3 देखें.

सत्यापन नियम
स्कीम

रीडायरेक्ट यूआरआई के लिए, एचटीटीपीएस स्कीम का इस्तेमाल करना ज़रूरी है, न कि एचटीटीपी का. लोकलहोस्ट यूआरआई (इनमें लोकलहोस्ट आईपी पते वाले यूआरआई भी शामिल हैं) पर यह नियम लागू नहीं होता.

होस्ट

होस्ट, रॉ आईपी पते नहीं हो सकते. Localhost आईपी पतों को इस नियम से छूट दी गई है.

डोमेन
  • होस्ट टीएलडी (टॉप लेवल डोमेन) सार्वजनिक सफ़िक्स सूची में शामिल होने चाहिए.
  • होस्ट डोमेन, “googleusercontent.com” नहीं हो सकते.
  • रीडायरेक्ट यूआरआई में, यूआरएल छोटा करने वाले डोमेन (जैसे, goo.gl) शामिल नहीं किए जा सकते. हालांकि, अगर ऐप्लिकेशन के पास डोमेन का मालिकाना हक है, तो ऐसा किया जा सकता है. इसके अलावा, अगर यूआरएल छोटा करने वाले डोमेन का मालिकाना हक रखने वाला कोई ऐप्लिकेशन, उस डोमेन पर रीडायरेक्ट करने का विकल्प चुनता है, तो उस रीडायरेक्ट यूआरआई के पाथ में “/google-callback/” शामिल होना चाहिए या वह “/google-callback” पर खत्म होना चाहिए.
  • Userinfo

    रीडायरेक्ट यूआरआई में, userinfo सबकॉम्पोनेंट शामिल नहीं हो सकता.

    पाथ

    रीडायरेक्ट यूआरआई में पाथ ट्रेवर्सल (इसे डायरेक्ट्री बैकट्रैकिंग भी कहा जाता है) शामिल नहीं हो सकता. इसे “/..” या “\..” या उनके यूआरएल एन्कोडिंग से दिखाया जाता है.

    क्वेरी

    रीडायरेक्ट यूआरआई में ओपन रीडायरेक्ट शामिल नहीं हो सकते.

    फ़्रैगमेंट

    रीडायरेक्ट यूआरआई में फ़्रैगमेंट कॉम्पोनेंट नहीं हो सकता.

    वर्ण रीडायरेक्ट यूआरआई में कुछ वर्ण शामिल नहीं किए जा सकते. जैसे:
    • वाइल्डकार्ड वर्ण ('*')
    • प्रिंट न किए जा सकने वाले ASCII वर्ण
    • अमान्य पर्सेंट एन्कोडिंग (कोई भी ऐसी पर्सेंट एन्कोडिंग जो यूआरएल-एन्कोडिंग का पालन नहीं करती है. इसमें प्रतिशत के चिह्न के बाद दो हेक्साडेसिमल अंक होते हैं)
    • नुल कैरेक्टर (एन्कोड किया गया NULL कैरेक्टर, जैसे कि %00, %C0%80)

    इंक्रीमेंटल ऑथराइज़ेशन

    OAuth 2.0 प्रोटोकॉल में, आपका ऐप्लिकेशन संसाधनों को ऐक्सेस करने की अनुमति का अनुरोध करता है. इन संसाधनों की पहचान, स्कोप से की जाती है. उपयोगकर्ता को बेहतर अनुभव देने के लिए, यह ज़रूरी है कि संसाधनों के ऐक्सेस की अनुमति उसी समय मांगी जाए जब आपको उनकी ज़रूरत हो. इस तरीके को चालू करने के लिए, Google का ऑथराइज़ेशन सर्वर, इंक्रीमेंटल ऑथराइज़ेशन की सुविधा देता है. इस सुविधा की मदद से, ज़रूरत के हिसाब से स्कोप का अनुरोध किया जा सकता है. अगर उपयोगकर्ता नए स्कोप के लिए अनुमति देता है, तो आपको एक ऑथराइज़ेशन कोड मिलेगा. इसे ऐसे टोकन से बदला जा सकता है जिसमें वे सभी स्कोप शामिल हों जिनके लिए उपयोगकर्ता ने प्रोजेक्ट को अनुमति दी है.

    उदाहरण के लिए, ऐसा ऐप्लिकेशन जो लोगों को म्यूज़िक ट्रैक के सैंपल सुनने और मिक्स बनाने की सुविधा देता है, उसे साइन-इन के समय बहुत कम संसाधनों की ज़रूरत पड़ सकती है. जैसे, साइन-इन करने वाले व्यक्ति के नाम के अलावा कुछ और नहीं. हालांकि, पूरे हो चुके मिक्स को सेव करने के लिए, उन्हें अपने Google Drive का ऐक्सेस देना होगा. ज़्यादातर लोगों को यह सामान्य लगता है कि जब ऐप्लिकेशन को वाकई Google Drive के ऐक्सेस की ज़रूरत हो, तब ही उनसे ऐक्सेस मांगा जाए.

    इस मामले में, साइन-इन करते समय ऐप्लिकेशन, साइन-इन करने की बुनियादी प्रोसेस को पूरा करने के लिए, openid और profile स्कोप का अनुरोध कर सकता है. इसके बाद, मिक्स को सेव करने के लिए पहले अनुरोध के समय, https://www.googleapis.com/auth/drive.file स्कोप का अनुरोध कर सकता है.

    इंक्रीमेंटल ऑथराइज़ेशन लागू करने के लिए, ऐक्सेस टोकन का अनुरोध करने का सामान्य तरीका अपनाएं. हालांकि, यह पक्का करें कि ऑथराइज़ेशन के अनुरोध में, पहले से दिए गए स्कोप शामिल हों. इस तरीके से, आपके ऐप्लिकेशन को कई ऐक्सेस टोकन मैनेज करने की ज़रूरत नहीं पड़ती.

    इंक्रीमेंटल ऑथराइज़ेशन से मिले ऐक्सेस टोकन पर ये नियम लागू होते हैं:

    • इस टोकन का इस्तेमाल, नए और संयुक्त अनुमति वाले स्कोप में शामिल किसी भी संसाधन को ऐक्सेस करने के लिए किया जा सकता है.
    • जब ऐक्सेस टोकन पाने के लिए, कंबाइंड ऑथराइज़ेशन के लिए रीफ़्रेश टोकन का इस्तेमाल किया जाता है, तो ऐक्सेस टोकन, कंबाइंड ऑथराइज़ेशन को दिखाता है. इसका इस्तेमाल, रिस्पॉन्स में शामिल किसी भी scope वैल्यू के लिए किया जा सकता है.
    • संयुक्त अनुमति में वे सभी स्कोप शामिल होते हैं जिन्हें उपयोगकर्ता ने एपीआई प्रोजेक्ट को दिया है. भले ही, अलग-अलग क्लाइंट से अनुमति का अनुरोध किया गया हो. उदाहरण के लिए, अगर किसी उपयोगकर्ता ने किसी ऐप्लिकेशन के डेस्कटॉप क्लाइंट का इस्तेमाल करके, एक स्कोप का ऐक्सेस दिया है और फिर उसी ऐप्लिकेशन को मोबाइल क्लाइंट के ज़रिए दूसरे स्कोप का ऐक्सेस दिया है, तो दोनों स्कोप को एक साथ अनुमति दी जाएगी.
    • अगर आपने एक से ज़्यादा अनुमतियों वाले टोकन को रद्द किया है, तो उस उपयोगकर्ता के लिए उस अनुमति के सभी स्कोप का ऐक्सेस एक साथ रद्द कर दिया जाता है.

    पहला चरण: Google के OAuth 2.0 सर्वर पर रीडायरेक्ट करने के लिए अनुमति सेट करना में, भाषा के हिसाब से दिए गए कोड सैंपल, इंक्रीमेंटल ऑथराइज़ेशन का इस्तेमाल करते हैं. नीचे दिए गए कोड सैंपल में, वह कोड भी दिखाया गया है जिसे आपको इंक्रीमेंटल ऑथराइज़ेशन का इस्तेमाल करने के लिए जोड़ना होगा.

    PHP

    $client->setIncludeGrantedScopes(true);

    Python

    Python में, include_granted_scopes कीवर्ड आर्ग्युमेंट को true पर सेट करें. इससे यह पक्का किया जा सकेगा कि अनुमति के अनुरोध में, पहले से दिए गए स्कोप शामिल हों. ऐसा हो सकता है कि include_granted_scopes, सेट किया गया एकमात्र कीवर्ड आर्ग्युमेंट न हो, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है.

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

    Ruby

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

    Node.js

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

    एचटीटीपी/आरईएसटी

    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//developers.google.com/oauthplayground&
      prompt=consent&
      include_granted_scopes=true

    ऐक्सेस टोकन को रीफ़्रेश करना (बिना इंटरनेट के इस्तेमाल)

    ऐक्सेस टोकन समय-समय पर खत्म हो जाते हैं और किसी एपीआई अनुरोध के लिए अमान्य क्रेडेंशियल बन जाते हैं. अगर आपने टोकन से जुड़े स्कोप के लिए ऑफ़लाइन ऐक्सेस का अनुरोध किया है, तो उपयोगकर्ता से अनुमति मांगे बिना ऐक्सेस टोकन को रीफ़्रेश किया जा सकता है. भले ही, उपयोगकर्ता मौजूद न हो.

    • अगर Google API क्लाइंट लाइब्रेरी का इस्तेमाल किया जाता है, तो क्लाइंट ऑब्जेक्ट ज़रूरत के हिसाब से ऐक्सेस टोकन को रीफ़्रेश करता है. हालांकि, इसके लिए ज़रूरी है कि आपने उस ऑब्जेक्ट को ऑफ़लाइन ऐक्सेस के लिए कॉन्फ़िगर किया हो.
    • अगर क्लाइंट लाइब्रेरी का इस्तेमाल नहीं किया जा रहा है, तो उपयोगकर्ता को Google के OAuth 2.0 सर्वर पर रीडायरेक्ट करते समय, आपको access_type एचटीटीपी क्वेरी पैरामीटर को offline पर सेट करना होगा. ऐसे में, जब ऐक्सेस टोकन के लिए ऑथराइज़ेशन कोड को एक्सचेंज किया जाता है, तब Google का ऑथराइज़ेशन सर्वर एक रीफ़्रेश टोकन दिखाता है. इसके बाद, अगर ऐक्सेस टोकन की समयसीमा खत्म हो जाती है (या किसी और समय), तो नया ऐक्सेस टोकन पाने के लिए, रीफ़्रेश टोकन का इस्तेमाल किया जा सकता है.

    अगर किसी ऐप्लिकेशन को उपयोगकर्ता की गैर-मौजूदगी में Google API को ऐक्सेस करना है, तो उसे ऑफ़लाइन ऐक्सेस का अनुरोध करना होगा. उदाहरण के लिए, बैकअप सेवाएं देने वाले या पहले से तय समय पर कार्रवाइयां करने वाले ऐप्लिकेशन को, उपयोगकर्ता के मौजूद न होने पर भी अपने ऐक्सेस टोकन को रीफ़्रेश करने की ज़रूरत होती है. ऐक्सेस के डिफ़ॉल्ट स्टाइल को online कहा जाता है.

    सर्वर-साइड वेब ऐप्लिकेशन, इंस्टॉल किए गए ऐप्लिकेशन, और डिवाइसों को अनुमति देने की प्रोसेस के दौरान, रीफ़्रेश टोकन मिलते हैं. आम तौर पर, क्लाइंट-साइड (JavaScript) वेब ऐप्लिकेशन में रीफ़्रेश टोकन का इस्तेमाल नहीं किया जाता.

    PHP

    अगर आपके ऐप्लिकेशन को Google API के बिना इंटरनेट के इस्तेमाल की ज़रूरत है, तो एपीआई क्लाइंट के ऐक्सेस टाइप को offline पर सेट करें:

    $client->setAccessType("offline");

    जब कोई उपयोगकर्ता, अनुरोध किए गए दायरों के लिए ऑफ़लाइन ऐक्सेस देता है, तब एपीआई क्लाइंट का इस्तेमाल जारी रखा जा सकता है. इससे उपयोगकर्ता के ऑफ़लाइन होने पर, उसकी ओर से Google API को ऐक्सेस किया जा सकता है. क्लाइंट ऑब्जेक्ट, ज़रूरत के हिसाब से ऐक्सेस टोकन को रीफ़्रेश करेगा.

    Python

    Python में, access_type कीवर्ड आर्ग्युमेंट को offline पर सेट करें. इससे यह पक्का किया जा सकेगा कि ऐक्सेस टोकन को रीफ़्रेश किया जा सकता है. इसके लिए, उपयोगकर्ता से अनुमति लेने के लिए फिर से अनुरोध करने की ज़रूरत नहीं पड़ेगी. यह काफ़ी हद तक मुमकिन है कि access_type, आपके सेट किए गए कीवर्ड का एकमात्र आर्ग्युमेंट न हो, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है.

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

    जब कोई उपयोगकर्ता, अनुरोध किए गए दायरों के लिए ऑफ़लाइन ऐक्सेस देता है, तब एपीआई क्लाइंट का इस्तेमाल जारी रखा जा सकता है. इससे उपयोगकर्ता के ऑफ़लाइन होने पर, उसकी ओर से Google API को ऐक्सेस किया जा सकता है. क्लाइंट ऑब्जेक्ट, ज़रूरत के हिसाब से ऐक्सेस टोकन को रीफ़्रेश करेगा.

    Ruby

    अगर आपके ऐप्लिकेशन को Google API के बिना इंटरनेट के इस्तेमाल की ज़रूरत है, तो एपीआई क्लाइंट के ऐक्सेस टाइप को offline पर सेट करें:

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

    जब कोई उपयोगकर्ता, अनुरोध किए गए दायरों के लिए ऑफ़लाइन ऐक्सेस देता है, तब एपीआई क्लाइंट का इस्तेमाल जारी रखा जा सकता है. इससे उपयोगकर्ता के ऑफ़लाइन होने पर, उसकी ओर से Google API को ऐक्सेस किया जा सकता है. क्लाइंट ऑब्जेक्ट, ज़रूरत के हिसाब से ऐक्सेस टोकन को रीफ़्रेश करेगा.

    Node.js

    अगर आपके ऐप्लिकेशन को 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
    });

    जब कोई उपयोगकर्ता, अनुरोध किए गए दायरों के लिए ऑफ़लाइन ऐक्सेस देता है, तब एपीआई क्लाइंट का इस्तेमाल जारी रखा जा सकता है. इससे उपयोगकर्ता के ऑफ़लाइन होने पर, उसकी ओर से 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`
    });

    क्लाइंट को रीफ़्रेश टोकन मिलने के बाद, एपीआई को किए जाने वाले अगले कॉल में ऐक्सेस टोकन अपने-आप मिल जाएंगे और रीफ़्रेश हो जाएंगे.

    एचटीटीपी/आरईएसटी

    ऐक्सेस टोकन को रीफ़्रेश करने के लिए, आपका ऐप्लिकेशन Google के ऑथराइज़ेशन सर्वर (https://oauth2.googleapis.com/token) को एचटीटीपीएस POST अनुरोध भेजता है. इस अनुरोध के मुख्य हिस्से में ये पैरामीटर शामिल होते हैं:

    नाम वैल्यू
    client_id API Console से मिला क्लाइंट आईडी.
    client_secret ज़रूरी नहीं

    API Console से मिला क्लाइंट सीक्रेट.

    grant_type OAuth 2.0 की खास जानकारी में बताए गए तरीके के मुताबिक, इस फ़ील्ड की वैल्यू refresh_token पर सेट होनी चाहिए.
    refresh_token ऑथराइज़ेशन कोड एक्सचेंज से मिला रीफ़्रेश टोकन.

    डीपीओपी का इस्तेमाल करना ज़रूरी नहीं है. हालांकि, बेहतर सुरक्षा के लिए इसका सुझाव दिया जाता है. रिफ़्रेश टोकन के साथ डीपीओपी का इस्तेमाल करने के लिए, आपके ऐप्लिकेशन को टोकन एंडपॉइंट के हर अनुरोध के लिए, एक नया और यूनीक डीपीओपी प्रूफ़ JWT जनरेट करना होगा. इस सबूत पर उसी निजी पासकोड से हस्ताक्षर किया जाना चाहिए जिसका इस्तेमाल, शुरुआती ऑथराइज़ेशन कोड एक्सचेंज के दौरान किया गया था. आपका ऐप्लिकेशन, सबूत को एचटीटीपी अनुरोध के हेडर के तौर पर जोड़ता है.

    हेडर ज़रूरी है ब्यौरा
    DPoP वैकल्पिक डीपीओपी प्रूफ़ एक जेडब्ल्यूटी है, जिससे निजी पासकोड के मालिकाना हक की पुष्टि होती है. यह एक हेडर है, न कि पैरामीटर. अगर टोकन दिए जाते हैं, तो वे इस कुंजी से जुड़े होते हैं. हर अनुरोध के लिए एक नया और यूनीक सबूत जनरेट किया जाना चाहिए. साथ ही, इसमें htm (एचटीटीपी तरीका) और htu (एचटीटीपी यूआरआई) दावे शामिल होने चाहिए, जो अनुरोध से मेल खाते हों.

    यहां दिए गए स्निपेट में, अनुरोध का एक सैंपल दिखाया गया है:

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

    रिफ़्रेश टोकन के साथ डीपीओपी का इस्तेमाल करने के लिए, आपको अनुरोध के लिए एक नया और यूनीक डीपीओपी प्रूफ़ JWT जनरेट करना होगा. कुंजी का जोड़ा जनरेट करने और JWT बनाने के सिलसिलेवार निर्देशों के लिए, DPoP प्रूफ़ बनाएं देखें.

    एक्सचेंज पूरा होने पर, 200 OK रिस्पॉन्स मिलता है. इसमें नया ऐक्सेस टोकन शामिल होता है. डीपीओपी का इस्तेमाल करने पर, token_type, Bearer होता है. सफल जवाब से पुष्टि होती है कि रीफ़्रेश टोकन के लिए, डीपीओपी के सबूत को स्वीकार कर लिया गया है. Google, जवाब में एक नया DPoP-Nonce एचटीटीपी हेडर भी दिखा सकता है. अगर ऐसा होता है, तो आपके क्लाइंट को इस नॉन्स को कैश मेमोरी में सेव करना होगा. साथ ही, बाद के अनुरोधों में डीपीओपी के सबूत के nonce दावे में इसे शामिल करना होगा.

    अगर DPoP हेडर मौजूद नहीं है, अमान्य है या गलत कुंजी का इस्तेमाल करता है, तो एक्सचेंज नहीं हो पाता. डीपीओपी की गड़बड़ी के खास कोड और नॉन्स को मैनेज करने के बारे में जानकारी पाने के लिए, एक्सचेंज नहीं हो सका लेख पढ़ें.

    यहां दिए गए स्निपेट में, डीपीओपी का इस्तेमाल करने पर मिलने वाले रिस्पॉन्स हेडर और मुख्य हिस्से का सैंपल दिखाया गया है:

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

    ध्यान दें कि जारी किए जाने वाले रीफ़्रेश टोकन की संख्या सीमित होती है. हर क्लाइंट/उपयोगकर्ता के कॉम्बिनेशन के लिए एक सीमा होती है. साथ ही, सभी क्लाइंट के लिए हर उपयोगकर्ता के हिसाब से एक सीमा होती है. आपको रीफ़्रेश टोकन को लंबे समय तक सेव करके रखना चाहिए. साथ ही, जब तक वे मान्य हैं, तब तक उनका इस्तेमाल करना चाहिए. अगर आपका ऐप्लिकेशन बहुत ज़्यादा रीफ़्रेश टोकन का अनुरोध करता है, तो हो सकता है कि वह इन सीमाओं को पार कर जाए. ऐसे में, पुराने रीफ़्रेश टोकन काम करना बंद कर देंगे.

    टोकन रद्द करना

    कुछ मामलों में, ऐसा हो सकता है कि कोई उपयोगकर्ता किसी ऐप्लिकेशन को दिया गया ऐक्सेस वापस लेना चाहे. उपयोगकर्ता खाते की सेटिंग में जाकर, ऐक्सेस वापस ले सकता है. ज़्यादा जानकारी के लिए, आपके खाते का ऐक्सेस रखने वाली तीसरे पक्ष की साइटें और ऐप्लिकेशन सहायता दस्तावेज़ का साइट या ऐप्लिकेशन का ऐक्सेस हटाएं सेक्शन देखें.

    ऐसा भी हो सकता है कि कोई ऐप्लिकेशन, प्रोग्राम के हिसाब से उसे दिए गए ऐक्सेस को रद्द कर दे. प्रोग्राम के हिसाब से टोकन रद्द करना उन मामलों में ज़रूरी है जहां कोई उपयोगकर्ता सदस्यता छोड़ देता है, किसी ऐप्लिकेशन को हटा देता है या किसी ऐप्लिकेशन के लिए ज़रूरी एपीआई संसाधनों में काफ़ी बदलाव हो गया है. दूसरे शब्दों में, ऐप्लिकेशन हटाने की प्रोसेस के तहत, एपीआई अनुरोध भी किया जा सकता है. इससे यह पक्का किया जा सकता है कि ऐप्लिकेशन को पहले दी गई अनुमतियां हटा दी गई हैं.

    PHP

    प्रोग्राम के हिसाब से टोकन रद्द करने के लिए, revokeToken() को कॉल करें:

    $client->revokeToken();

    Python

    प्रोग्राम के हिसाब से टोकन को रद्द करने के लिए, https://oauth2.googleapis.com/revoke को अनुरोध भेजें. इसमें टोकन को पैरामीटर के तौर पर शामिल करें और Content-Type हेडर सेट करें:

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

    Ruby

    प्रोग्राम के हिसाब से टोकन रद्द करने के लिए, oauth2.revoke एंडपॉइंट पर एचटीटीपी अनुरोध करें:

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

    टोकन, ऐक्सेस टोकन या रीफ़्रेश टोकन हो सकता है. अगर टोकन एक ऐक्सेस टोकन है और उससे जुड़ा कोई रीफ़्रेश टोकन है, तो रीफ़्रेश टोकन भी रद्द कर दिया जाएगा.

    अगर टोकन को रद्द करने की प्रोसेस पूरी हो जाती है, तो जवाब का स्टेटस कोड 200 होता है. गड़बड़ी की स्थितियों के लिए, गड़बड़ी के कोड के साथ स्टेटस कोड 400 दिखाया जाता है.

    Node.js

    प्रोग्राम के हिसाब से टोकन रद्द करने के लिए, /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 दिखाया जाता है.

    एचटीटीपी/आरईएसटी

    प्रोग्राम के हिसाब से टोकन रद्द करने के लिए, आपका ऐप्लिकेशन https://oauth2.googleapis.com/revoke को अनुरोध भेजता है और टोकन को पैरामीटर के तौर पर शामिल करता है:

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

    टोकन, ऐक्सेस टोकन या रीफ़्रेश टोकन हो सकता है. अगर टोकन एक ऐक्सेस टोकन है और उससे जुड़ा कोई रीफ़्रेश टोकन है, तो रीफ़्रेश टोकन भी रद्द कर दिया जाएगा.

    अगर टोकन रद्द करने की प्रोसेस पूरी हो जाती है, तो जवाब का एचटीटीपी स्टेटस कोड 200 होता है. गड़बड़ी की स्थितियों के लिए, गड़बड़ी के कोड के साथ एचटीटीपी स्टेटस कोड 400 दिखाया जाता है.

    समय के हिसाब से ऐक्सेस

    समय के हिसाब से ऐक्सेस देने की सुविधा से, उपयोगकर्ता आपके ऐप्लिकेशन को सीमित समय के लिए अपने डेटा का ऐक्सेस दे सकता है, ताकि कोई कार्रवाई पूरी की जा सके. सहमति देने की प्रोसेस के दौरान, Google के चुनिंदा प्रॉडक्ट में समय के हिसाब से ऐक्सेस देने की सुविधा उपलब्ध है. इससे उपयोगकर्ताओं को सीमित समय के लिए ऐक्सेस देने का विकल्प मिलता है. इसका एक उदाहरण Data Portability API है. इसकी मदद से, डेटा को एक बार ट्रांसफ़र किया जा सकता है.

    जब कोई उपयोगकर्ता आपके ऐप्लिकेशन को समय के हिसाब से ऐक्सेस देता है, तो तय की गई अवधि के बाद रीफ़्रेश टोकन की समयसीमा खत्म हो जाएगी. ध्यान दें कि कुछ मामलों में, रीफ़्रेश टोकन पहले भी अमान्य हो सकते हैं. ज़्यादा जानकारी के लिए, ये मामले देखें. ऑथराइज़ेशन कोड एक्सचेंज रिस्पॉन्स में दिखाया गया refresh_token_expires_in फ़ील्ड, ऐसे मामलों में रीफ़्रेश टोकन की समयसीमा खत्म होने तक बचे हुए समय को दिखाता है.

    'सभी खातों की सुरक्षा' सुविधा को लागू करना

    अपने उपयोगकर्ताओं के खातों को सुरक्षित रखने के लिए, आपको एक और कदम उठाना चाहिए. इसके लिए, Google की सभी खातों की सुरक्षा सेवा का इस्तेमाल करके, सभी खातों की सुरक्षा की सुविधा लागू करें. इस सेवा की मदद से, सुरक्षा से जुड़ी गतिविधि की सूचनाओं की सदस्यता ली जा सकती है. इससे आपके ऐप्लिकेशन को उपयोगकर्ता खाते में हुए अहम बदलावों की जानकारी मिलती है. इसके बाद, इस जानकारी का इस्तेमाल करके, इवेंट के हिसाब से कार्रवाई की जा सकती है.

    Google की सभी खातों की सुरक्षा सेवा, आपके ऐप्लिकेशन को कुछ इवेंट भेजती है. इनके कुछ उदाहरण यहां दिए गए हैं:

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

    सभी खातों की सुरक्षा की सुविधा को लागू करने के तरीके और उपलब्ध इवेंट की पूरी सूची के बारे में ज़्यादा जानने के लिए, सभी खातों की सुरक्षा की सुविधा की मदद से उपयोगकर्ता खातों को सुरक्षित करना पेज देखें.