يجب أن تتوافق تطبيقات المحادثات التي تستخدم مصادقة المستخدم مع أذونات OAuth الدقيقة للسماح للمستخدمين بمنح مجموعة فرعية من النطاقات المطلوبة. على سبيل المثال، قد يمنح المستخدم إذن الوصول إلى اسمه ولكن يرفض منح إذن الوصول إلى تقويمه.
تعتمد طريقة التعامل مع أذونات OAuth الدقيقة على طريقة إنشاء تطبيق Chat:
- إضافات Google Workspace في "برمجة تطبيقات Google" التي توسّع نطاق Chat
- تطبيقات Chat المستقلة في "برمجة تطبيقات Google"
- إضافات HTTP في Google Workspace التي توسّع نطاق Chat
- تطبيقات Chat المستقلة المستندة إلى HTTP
برمجة التطبيقات
إذا أنشأت تطبيق Chat باستخدام برمجة تطبيقات Google، ستتعامل "برمجة تطبيقات Google" مع أذونات OAuth الدقيقة تلقائيًا. ومع ذلك، تأكَّد من أنّ الرمز البرمجي يعالج الحالات التي لا يمنح فيها المستخدم جميع النطاقات المطلوبة. تعتمد الطريقة على ما إذا كانت برمجة التطبيقات هي إضافة Google Workspace توسّع نطاق Google Chat باستخدام برمجة التطبيقات أو تطبيق Chat مستقل تم إنشاؤه باستخدام برمجة التطبيقات وأحداث التفاعل.
إضافات Google Workspace التي توسّع نطاق Chat
إذا أنشأت تطبيق Chat كـ إضافة Google Workspace توسّع نطاق Google Chat باستخدام "برمجة تطبيقات Google"، اتّبِع التعليمات الواردة في التعامل مع أذونات OAuth الدقيقة في "برمجة تطبيقات Google".
تطبيقات Chat المستقلة المستندة إلى Apps Script
إذا أنشأت تطبيق Chat باستخدام برمجة تطبيقات Google وأحداث التفاعل، ستعمل التعليمات الواردة في التعامل مع أذونات OAuth الدقيقة في "برمجة تطبيقات Google" مع مراعاة ما يلي:
يؤدي ScriptApp.requireScopes إلى
إيقاف تنفيذ البرنامج النصي إذا لم يتم منح النطاقات المحدّدة،
ولكن يرى المستخدم بطاقة إعداد في Chat
بدلاً من شاشة الموافقة على OAuth. تطلب بطاقة الإعداد دائمًا من المستخدم منح جميع النطاقات المطلوبة بدلاً من النطاقات التي لم يتم منحها فقط.
لتقديم عمليات تحقّق على مستوى نطاق التفويض الفردي، استخدِم
ScriptApp.getAuthorizationInfo
للتحقّق من التفويض، وإذا لزم الأمر، اطلب التفويض باستخدام
رسالة خاصة.
يوضّح المثال التالي كيفية التحقّق من توفّر إذن معيّن (مثل إذن الوصول إلى التقويم)، وفي حال عدم توفّره، يتم عرض رسالة خاصة تتضمّن عنوان URL الخاص بالتفويض المطلوب.
برمجة التطبيقات
/**
* 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.
// ...
}
نقاط نهاية HTTP
إذا أنشأت تطبيق Chat باستخدام نقاط نهاية HTTP، يجب أن يتيح تطبيق Chat أذونات OAuth دقيقة.
إضافات Google Workspace التي توسّع نطاق Chat
إذا أنشأت تطبيق Chat كـ إضافة Google Workspace (على سبيل المثال، إذا كان يوسّع تطبيقات Google Workspace الأخرى، مثل Google Drive أو Gmail)، عليك ضبط ملف البيان والرمز البرمجي للتعامل مع أذونات OAuth الدقيقة:
في ملف البيان الخاص بالإضافة، اضبط الحقل
granularOauthPermissionSupportعلىOPT_IN. لمزيد من المعلومات حول الحقلgranularOauthPermissionSupport، يُرجى الاطّلاع على الانتقال إلى مسار أذونات OAuth الدقيقة.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": {}, "httpOptions": { "granularOauthPermissionSupport": "OPT_IN" } } }للاطّلاع على النطاقات التي منحها المستخدم، تحقَّق من الحقل
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'] } })جافا
import com.google.gson.JsonArray; import com.google.gson.JsonObject; import java.util.List; // Check for authorized scopes. List<String> authorizedScopes = event.getAuthorizationEventObject().getAuthorizedScopes(); if (!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(); }لطلب جميع النطاقات المرتبطة بالإضافة، اضبط
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 } })جافا
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 التي تستخدم HTTP.
تطبيقات محادثة HTTP المستقلة
إذا كان تطبيق Chat عبارة عن خدمة HTTP مستقلة (وليست إضافة في Google Workspace)، عليك إدارة عملية 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'
)
جافا
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();
لمزيد من المعلومات، يُرجى الاطّلاع على أذونات OAuth الدقيقة.
مواضيع ذات صلة
- للحصول على نظرة عامة حول المصادقة والتفويض في Google Chat، يُرجى الاطّلاع على مقالة التعرّف على المصادقة والتفويض.
- لإعداد مصادقة المستخدم، يُرجى الاطّلاع على مقالة المصادقة والتفويض كمستخدم في Google Chat.
- للحصول على المساعدة في إعداد أذونات OAuth الدقيقة في "برمجة تطبيقات Google" أو لإضافات HTTP Google Workspace، يُرجى الاطّلاع على:
- لمزيد من المعلومات حول أذونات OAuth الدقيقة، يُرجى الاطّلاع على أذونات OAuth الدقيقة.