Google Chat ऐप्लिकेशन के लिए, OAuth की ज़्यादा बेहतर अनुमतियां मैनेज करना

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

OAuth की अनुमतियों को मैनेज करने का तरीका, इस बात पर निर्भर करता है कि आपने Chat ऐप्लिकेशन कैसे बनाया है:

Apps Script

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

एचटीटीपी एंडपॉइंट

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

  1. Chat ऐप्लिकेशन की मेनिफ़ेस्ट फ़ाइल में, oauthScopes फ़ील्ड में ज़रूरी अनुमति के स्कोप तय करें. यह फ़ील्ड, projects.deployments रिसॉर्स का हिस्सा है.

    यहां दिए गए उदाहरण के लिए, chat.messages और calendar.events ऑथराइज़ेशन स्कोप की ज़रूरत होती है:

    JSON

    {
      "oauthScopes": [
        "https://www.googleapis.com/auth/chat.messages",
        "https://www.googleapis.com/auth/calendar.events"
      ],
      "addOns": {
        "common": {
          "name": "My Chat App",
          "logoUrl": "https://lh3.googleusercontent.com/..."
        },
        "chat": {},
        "calendar": {},
        "httpOptions": {}
      }
    }
    
  2. उपयोगकर्ता ने किन स्कोप का ऐक्सेस दिया है, यह देखने के लिए authorizationEventObject.authorizedScopes फ़ील्ड देखें. अगर कोई ज़रूरी स्कोप मौजूद नहीं है, तो requesting_google_scopes कार्रवाई करके उपयोगकर्ता को उस स्कोप के बारे में बताएं.

    Node.js

    // Check for authorized scopes.
    const authorizedScopes = req.body.authorizationEventObject?.authorizedScopes || [];
    if (!authorizedScopes.includes('https://www.googleapis.com/auth/chat.messages')) {
      // Respond with a request for the missing scope.
      res.send({
        'requesting_google_scopes': {
          'scopes': ['https://www.googleapis.com/auth/chat.messages']
        }
      });
      return;
    }
    

    Python

    from flask import jsonify, request
    
    # Check for authorized scopes.
    event_data = request.get_json()
    authorized_scopes = event_data.get('authorizationEventObject', {}).get('authorizedScopes', [])
    if 'https://www.googleapis.com/auth/chat.messages' not in authorized_scopes:
        # Respond with a request for the missing scope.
        return jsonify({
            'requesting_google_scopes': {
                'scopes': ['https://www.googleapis.com/auth/chat.messages']
            }
        })
    

    Java

    import com.google.gson.JsonArray;
    import com.google.gson.JsonObject;
    import java.util.List;
    
    // Check for authorized scopes.
    List<String> authorizedScopes = event.getAuthorizationEventObject() != null
        ? event.getAuthorizationEventObject().getAuthorizedScopes()
        : null;
    if (authorizedScopes == null || !authorizedScopes.contains("https://www.googleapis.com/auth/chat.messages")) {
      // Respond with a request for the missing scope.
      JsonObject requestingGoogleScopes = new JsonObject();
      JsonArray scopes = new JsonArray();
      scopes.add("https://www.googleapis.com/auth/chat.messages");
      requestingGoogleScopes.add("scopes", scopes);
    
      JsonObject response = new JsonObject();
      response.add("requesting_google_scopes", requestingGoogleScopes);
      return response.toString();
    }
    

    Chat ऐप्लिकेशन से जुड़े सभी स्कोप का अनुरोध करने के लिए, all_scopes को true पर सेट करें:

    Node.js

    res.send({
      'requesting_google_scopes': { 'all_scopes': true }
    });
    

    Python

    from flask import jsonify
    
    return jsonify({
        'requesting_google_scopes': { 'all_scopes': True }
    })
    

    Java

    import com.google.gson.JsonObject;
    
    JsonObject requestingGoogleScopes = new JsonObject();
    requestingGoogleScopes.addProperty("all_scopes", true);
    
    JsonObject response = new JsonObject();
    response.add("requesting_google_scopes", requestingGoogleScopes);
    return response.toString();
    

ज़्यादा जानकारी के लिए, एचटीटीपी Google Workspace ऐड-ऑन के लिए, ज़्यादा कंट्रोल वाली अनुमतियां मैनेज करना लेख पढ़ें.

ऐसे चैट ऐप्लिकेशन जो ऐड-ऑन नहीं हैं: Google Chat ऐप्लिकेशन के लिए, OAuth की ज़्यादा अनुमतियां मैनेज करना

अगर आपको ऐसे Chat ऐप्लिकेशन को मैनेज करना है जो Google Workspace ऐड-ऑन नहीं है, तो OAuth की अनुमतियों को मैनेज करने के लिए यहां दिए गए निर्देशों का पालन करें.

Apps Script की मदद से बनाए गए ऐसे Chat ऐप्लिकेशन जो ऐड-ऑन नहीं हैं

अगर आपने Apps Script का इस्तेमाल करके कोई ऐसा Chat ऐप्लिकेशन बनाया है जो ऐड-ऑन नहीं है, तो Apps Script में OAuth की ज़्यादा अनुमतियों को मैनेज करना में दिए गए निर्देश लागू होंगे. हालांकि, इसके लिए आपको एक बात का ध्यान रखना होगा:

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

अनुमति के स्कोप के लेवल पर अलग-अलग जांच करने के लिए, ScriptApp.getAuthorizationInfo का इस्तेमाल करें. इससे अनुमति की जांच की जा सकती है. साथ ही, अगर ज़रूरी हो, तो निजी मैसेज का इस्तेमाल करके अनुमति का अनुरोध किया जा सकता है.

यहां दिए गए उदाहरण में, किसी खास अनुमति (जैसे, कैलेंडर ऐक्सेस) की जांच करने का तरीका बताया गया है. साथ ही, अगर अनुमति नहीं है, तो ज़रूरी अनुमति वाले यूआरएल के साथ एक निजी मैसेज भेजने का तरीका बताया गया है.

Apps Script

/**
* Responds to a MESSAGE event in Google Chat.
* Checks for required permissions and if missing asks for them.
*
* @param {Object} event the event object from Chat
* @return {Object} JSON response
*/
function onMessage(event) {
  // Check if the script has the necessary permissions.
  // In this example, the script checks for the "calendar.events" scope.
  var requiredScopes = ['https://www.googleapis.com/auth/calendar.events'];
  var authInfo = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL, requiredScopes);

  // If permissions are missing, return a message with the authorization URL.
  if (authInfo.getAuthorizationStatus() === ScriptApp.AuthorizationStatus.REQUIRED) {
    var authUrl = authInfo.getAuthorizationUrl();
    return {
      "text": "This action requires authorization. Please <" + authUrl + "|click here to authorize>.",
      "privateMessageViewer": {
        "name": event.user.name
      }
    };
  }

  // Permission granted; proceed with the application logic.
  // ...
}

एचटीटीपी Chat ऐप्लिकेशन, जो ऐड-ऑन नहीं हैं

अगर आपका Chat ऐप्लिकेशन, ऐड-ऑन नहीं है और एचटीटीपी सेवा है, तो आपको OAuth 2.0 फ़्लो को खुद मैनेज करना होगा.

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

Node.js

// 1. List authorized scopes.
const fs = require('fs');
const tokens = JSON.parse(fs.readFileSync('token.json'));
const grantedScopes = tokens.scope.split(' ');

// 2. Detect missing scopes.
const requiredScopes = ['https://www.googleapis.com/auth/chat.messages'];
const missingScopes = requiredScopes.filter(scope => !grantedScopes.includes(scope));

if (missingScopes.length > 0) {
  // 3. Request missing scopes.
  const authUrl = oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: missingScopes,
    include_granted_scopes: true
  });
  res.redirect(authUrl);
}

// To request all scopes instead of just the missing ones:
const allScopesAuthUrl = oauth2Client.generateAuthUrl({
  access_type: 'offline',
  scope: requiredScopes,
  include_granted_scopes: true
});

Python

from flask import redirect
from google.oauth2.credentials import Credentials

# 1. List authorized scopes.
credentials = Credentials.from_authorized_user_file('token.json')
granted_scopes = set(credentials.scopes)

# 2. Detect missing scopes.
required_scopes = {'https://www.googleapis.com/auth/chat.messages'}
missing_scopes = required_scopes - granted_scopes

if missing_scopes:
    # 3. Request missing scopes.
    flow.scope = list(missing_scopes)
    auth_url, _ = flow.authorization_url(
        access_type='offline',
        include_granted_scopes=True
    )
    return redirect(auth_url)

# To request all scopes instead of just the missing ones:
flow.scope = list(required_scopes)
all_scopes_auth_url, _ = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true'
)

Java

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

// 1. List authorized scopes.
// The "user" string is the user ID for which to load credentials.
Credential credential = flow.loadCredential("user");
Collection<String> grantedScopes = credential.getScopes();

// 2. Detect missing scopes.
// The `requiredScopes` variable contains a list of the OAuth scopes
// that your app requires to function. Define this variable with the
// scopes needed by your application.
List<String> requiredScopes = Arrays.asList("https://www.googleapis.com/auth/chat.messages");
List<String> missingScopes = new ArrayList<>();
for (String scope : requiredScopes) {
  if (!grantedScopes.contains(scope)) {
    missingScopes.add(scope);
  }
}

if (!missingScopes.isEmpty()) {
  // 3. Request missing scopes.
  GoogleAuthorizationCodeRequestUrl urlBuilder = new GoogleAuthorizationCodeRequestUrl(
      clientId, redirectUri, missingScopes)
      .setAccessType("offline")
      .set("include_granted_scopes", "true");
  String authUrl = urlBuilder.build();
  response.sendRedirect(authUrl);
}

// To request all scopes instead of just the missing ones:
GoogleAuthorizationCodeRequestUrl allScopesUrlBuilder = new GoogleAuthorizationCodeRequestUrl(
    clientId, redirectUri, requiredScopes)
    .setAccessType("offline")
    .set("include_granted_scopes", "true");
String allScopesAuthUrl = allScopesUrlBuilder.build();