
Jeśli Twój dodatek do Google Workspace łączy się z usługą lub interfejsem API innej firmy, która wymaga autoryzacji, może wyświetlić użytkownikom prośbę o zalogowanie się i autoryzację dostępu.
Na tej stronie wyjaśniamy, jak uwierzytelniać użytkowników za pomocą procesu autoryzacji (np. OAuth), który obejmuje te kroki:
- wykrywać, kiedy wymagana jest autoryzacja;
- Zwraca interfejs karty, który prosi użytkowników o zalogowanie się w usłudze.
- Odśwież dodatek, aby użytkownicy mogli uzyskać dostęp do usługi lub chronionego zasobu.
Jeśli Twój dodatek wymaga tylko tożsamości użytkownika, możesz uwierzytelnić użytkowników bezpośrednio, używając ich identyfikatora Google Workspace lub adresu e-mail. Aby używać adresu e-mail do uwierzytelniania, zapoznaj się z artykułem Walidowanie żądań JSON. Jeśli Twój dodatek został utworzony za pomocą Google Apps Script, możesz ułatwić ten proces, korzystając z biblioteki OAuth2 dla Google Apps Script (dostępna jest też wersja OAuth1).
wykrywanie, że wymagana jest autoryzacja;
Podczas korzystania z Twojego dodatku użytkownicy mogą nie mieć uprawnień do dostępu do zasobu chronionego z różnych powodów, takich jak:
- Token dostępu do usługi innej firmy nie został jeszcze wygenerowany lub wygasł.
- Token dostępu nie obejmuje żądanego zasobu.
- Token dostępu nie obejmuje wymaganych zakresów żądania.
Twój dodatek powinien wykrywać takie przypadki, aby użytkownicy mogli zalogować się i uzyskać dostęp do Twojej usługi.
Jeśli tworzysz aplikację w Apps Script, funkcja biblioteki OAuth
hasAccess()
może Ci pomóc sprawdzić, czy masz dostęp do usługi.
Jeśli używasz żądań UrlFetchApp fetch()
, możesz ustawić parametr muteHttpExceptions
na true
. Zapobiega to zgłaszaniu wyjątku przez żądanie w przypadku niepowodzenia żądania i umożliwia sprawdzenie kodu odpowiedzi żądania oraz treści w zwróconym obiekcie HttpResponse
.
Zachęcaj użytkowników do zalogowania się w usłudze
Gdy dodatek wykryje, że wymagane jest uwierzytelnianie, musi zwrócić interfejs karty, aby zachęcić użytkowników do zalogowania się w usłudze. Karta logowania musi przekierowywać użytkowników do procesu uwierzytelniania i autoryzacji w Twojej infrastrukturze.
Podczas tworzenia dodatku za pomocą punktów końcowych HTTP zalecamy zabezpieczenie aplikacji docelowej za pomocą logowania przez Google. Aby uzyskać identyfikator użytkownika, użyj tokenu tożsamości wydanego podczas logowania. Zawiera on unikalny identyfikator użytkownika i może być powiązany z identyfikatorem z Twojego dodatku.
Tworzenie i zwracanie karty logowania
W przypadku karty logowania do usługi możesz użyć podstawowej karty autoryzacyjnej Google lub spersonalizować kartę, aby wyświetlać dodatkowe informacje, takie jak logo organizacji. Jeśli publikujesz dodatek publicznie, musisz użyć karty niestandardowej.
Podstawowa karta autoryzacji
Na poniższym obrazku widać przykładową kartę autoryzacji Google:

Aby wyświetlić użytkownikom kartę autoryzacji podstawowej, musisz zwrócić obiekt.AuthorizationError
Poniższy kod pokazuje przykład obiektu AuthorizationError
:
Google Apps Script
CardService.newAuthorizationException() .setAuthorizationUrl('AUTHORIZATION_URL') .setResourceDisplayName('RESOURCE_DISPLAY_NAME') .throwException();
JSON
Zwracaj tę odpowiedź JSON:
{
"basic_authorization_prompt": {
"authorization_url": "AUTHORIZATION_URL",
"resource": "RESOURCE_DISPLAY_NAME"
}
}
Zastąp następujące elementy:
AUTHORIZATION_URL
: adres URL aplikacji internetowej, która obsługuje autoryzację.RESOURCE_DISPLAY_NAME
: wyświetlana nazwa chronionego zasobu lub usługi. Ta nazwa jest wyświetlana użytkownikowi w prośbie o autoryzację. Jeśli na przykładRESOURCE_DISPLAY_NAME
toExample Account
, pojawi się komunikat „Ten dodatek chce wyświetlić dodatkowe informacje, ale w tym celu potrzebuje zgody na dostęp do Twojego konta Example”.
Po zakończeniu autoryzacji użytkownik zostanie poproszony o odświeżenie dodatku, aby uzyskać dostęp do zasobu chronionego.
Zwrot karty autoryzacyjnej w Google Chat
Jeśli Twój dodatek rozszerza Google Chat, a użytkownik uruchomi go w Google Chat, może dokończyć proces autoryzacji bez ręcznego odświeżania. Google Chat obsługuje automatyczne ponowne próby poprzedniego wykonania, jeśli reguła to Wiadomość, Dodano do pokoju lub Polecenie aplikacji. W przypadku tych reguł w ładunku zdarzenia dodatek otrzymuje wartość completeRedirectUri
.
Aby wywołać automatyczne ponowne próby, musisz zakodować wartość completeRedirectUri
w adresie URL konfiguracji. Przekierowanie na ten adres URL sygnalizuje Google Chat, że żądanie konfiguracji zostało spełnione, i pozwala Google Chat na ponowne wykonanie poprzedniego wykonania.
Gdy użytkownik zostanie przekierowany do configCompleteRedirectUrl
podanego w oryginalnej wiadomości, Google Chat wykona te czynności:
- Usuwa prompt wyświetlany użytkownikowi inicjującemu.
- Po raz drugi wysyła pierwotny obiekt zdarzenia do tego samego dodatku.
Jeśli nie zakodujesz parametru completeRedirectUri
w adresie URL konfiguracji, użytkownik nadal może przejść proces autoryzacji. Google Chat nie próbuje jednak ponownie wykonać poprzedniego polecenia, dlatego użytkownik musi ponownie wywołać wtyczkę ręcznie.
Karta autoryzacji niestandardowej
Aby zmodyfikować prośbę o autoryzację, możesz utworzyć kartę niestandardową na potrzeby logowania w usłudze.
Jeśli publikujesz dodatek publicznie, musisz użyć niestandardowej karty autoryzacyjnej. Więcej informacji o wymaganiach dotyczących publikowania aplikacji w Google Workspace Marketplace znajdziesz w artykule Sprawdzanie aplikacji.
Zwrócona karta musi:
- Jasno poinformuj użytkownika, że dodatek prosi o pozwolenie na dostęp do usługi innej niż Google w imieniu użytkownika.
- Jasno określ, co dodatek może zrobić, jeśli zostanie autoryzowany.
- Zawierać przycisk lub podobny widżet, który przekierowuje użytkownika do adresu URL autoryzacji usługi. Upewnij się, że funkcja widżetu jest oczywista dla użytkownika.
- Powyższy widżet musi używać ustawienia
OnClose.RELOAD
w obiekcieOpenLink
, aby można było ponownie załadować dodatek po otrzymaniu autoryzacji. - Wszystkie linki otwierane z prośby o autoryzację muszą korzystać z protokołu HTTPS.
Na ilustracji poniżej widać przykładową kartę autoryzacji niestandardowej na stronie głównej dodatku. Karta zawiera logo, opis i przycisk logowania:

Poniższy kod pokazuje, jak używać tego przykładu karty niestandardowej:
Google Apps Script
function customAuthorizationCard() {
let cardSection1Image1 = CardService.newImage()
.setImageUrl('LOGO_URL')
.setAltText('LOGO_ALT_TEXT');
let cardSection1Divider1 = CardService.newDivider();
let cardSection1TextParagraph1 = CardService.newTextParagraph()
.setText('DESCRIPTION');
let cardSection1ButtonList1Button1 = CardService.newTextButton()
.setText('Sign in')
.setBackgroundColor('#0055ff')
.setTextButtonStyle(CardService.TextButtonStyle.FILLED)
.setAuthorizationAction(CardService.newAuthorizationAction()
.setAuthorizationUrl('AUTHORIZATION_URL'));
let cardSection1ButtonList1 = CardService.newButtonSet()
.addButton(cardSection1ButtonList1Button1);
let cardSection1TextParagraph2 = CardService.newTextParagraph()
.setText('TEXT_SIGN_UP');
let cardSection1 = CardService.newCardSection()
.addWidget(cardSection1Image1)
.addWidget(cardSection1Divider1)
.addWidget(cardSection1TextParagraph1)
.addWidget(cardSection1ButtonList1)
.addWidget(cardSection1TextParagraph2);
let card = CardService.newCardBuilder()
.addSection(cardSection1)
.build();
return [card];
}
function startNonGoogleAuth() {
CardService.newAuthorizationException()
.setAuthorizationUrl('AUTHORIZATION_URL')
.setResourceDisplayName('RESOURCE_DISPLAY_NAME')
.setCustomUiCallback('customAuthorizationCard')
.throwException();
}
JSON
Zwracaj tę odpowiedź JSON:
{
"custom_authorization_prompt": {
"action": {
"navigations": [
{
"pushCard": {
"sections": [
{
"widgets": [
{
"image": {
"imageUrl": "LOGO_URL",
"altText": "LOGO_ALT_TEXT"
}
},
{
"divider": {}
},
{
"textParagraph": {
"text": "DESCRIPTION"
}
},
{
"buttonList": {
"buttons": [
{
"text": "Sign in",
"onClick": {
"openLink": {
"url": "AUTHORIZATION_URL",
"onClose": "RELOAD",
"openAs": "OVERLAY"
}
},
"color": {
"red": 0,
"green": 0,
"blue": 1,
"alpha": 1,
}
}
]
}
},
{
"textParagraph": {
"text": "TEXT_SIGN_UP"
}
}
]
}
]
}
}
]
}
}
}
Zastąp następujące elementy:
LOGO_URL
: adres URL logo lub obrazu. Musi to być publiczny adres URL.LOGO_ALT_TEXT
: tekst alternatywny logo lub obrazu, np.Cymbal Labs Logo
.DESCRIPTION
: wezwanie do działania, aby użytkownicy mogli się zalogować, na przykładSign in to get started
.- Aby zaktualizować przycisk logowania:
AUTHORIZATION_URL
: adres URL aplikacji internetowej, która obsługuje autoryzację.- Opcjonalnie: aby zmienić kolor przycisku, zaktualizuj wartości zmiennoprzecinkowe RGBA pola
color
. W przypadku Apps Script zaktualizuj metodęsetBackgroundColor()
, używając wartości szesnastkowych.
TEXT_SIGN_UP
: tekst zachęcający użytkowników do utworzenia konta, jeśli go nie mają. Na przykład:New to Cymbal Labs? <a href=\"https://www.example.com/signup\">Sign up</a> here
.
Zarządzanie logowaniem się w aplikacjach Google Workspace za pomocą kont innych firm
Jednym z typowych zastosowań dodatków do Google Workspace jest udostępnianie interfejsu do interakcji z systemem innej firmy z poziomu aplikacji hosta Google Workspace.
Systemy innych firm często wymagają, aby użytkownik zalogował się, podając identyfikator użytkownika, hasło lub inne dane logowania. Gdy użytkownik loguje się w usłudze innej firmy, korzystając z jednego hosta Google Workspace, musisz się upewnić, że nie musi logować się ponownie, gdy przełączy się na innego hosta Google Workspace.
Jeśli tworzysz aplikację w Apps Script, możesz uniemożliwić powtarzające się żądania logowania za pomocą właściwości użytkownika lub tokenów identyfikacyjnych. W następnych sekcjach omawiamy te opcje.
Właściwości użytkownika
Dane logowania użytkownika możesz przechowywać w właściwościach użytkownika w Google Apps Script. Możesz na przykład utworzyć własny token sieciowy JSON (JWT) z usługi logowania i zapisać go w właściwości użytkownika lub zapisać nazwę użytkownika i hasło do tej usługi.
Właściwości użytkownika są ograniczone tak, aby były dostępne tylko dla tego użytkownika w skrypcie dodatku. Inni użytkownicy i inne skrypty nie mają dostępu do tych właściwości. Więcej informacji znajdziesz w sekcji PropertiesService
.
tokeny identyfikatora;
Jako danych logowania do usługi możesz użyć tokenu Google ID. Jest to sposób na logowanie jednokrotne. Użytkownicy są już zalogowani w Google, ponieważ znajdują się w aplikacji hosta Google.
Przykład konfiguracji OAuth innej niż Google
Poniższy przykładowy kod Apps Script pokazuje, jak skonfigurować dodatek do korzystania z interfejsu API spoza Google, który wymaga uwierzytelniania OAuth. Ten przykład korzysta z biblioteki OAuth2 dla Apps Script do tworzenia usługi dostępu do interfejsu API.
Google Apps Script
/**
* Attempts to access a non-Google API using a constructed service
* object.
*
* If your add-on needs access to non-Google APIs that require OAuth,
* you need to implement this method. You can use the OAuth1 and
* OAuth2 Apps Script libraries to help implement it.
*
* @param {String} url The URL to access.
* @param {String} method_opt The HTTP method. Defaults to GET.
* @param {Object} headers_opt The HTTP headers. Defaults to an empty
* object. The Authorization field is added
* to the headers in this method.
* @return {HttpResponse} the result from the UrlFetchApp.fetch() call.
*/
function accessProtectedResource(url, method_opt, headers_opt) {
var service = getOAuthService();
var maybeAuthorized = service.hasAccess();
if (maybeAuthorized) {
// A token is present, but it may be expired or invalid. Make a
// request and check the response code to be sure.
// Make the UrlFetch request and return the result.
var accessToken = service.getAccessToken();
var method = method_opt || 'get';
var headers = headers_opt || {};
headers['Authorization'] =
Utilities.formatString('Bearer %s', accessToken);
var resp = UrlFetchApp.fetch(url, {
'headers': headers,
'method' : method,
'muteHttpExceptions': true, // Prevents thrown HTTP exceptions.
});
var code = resp.getResponseCode();
if (code >= 200 && code < 300) {
return resp.getContentText("utf-8"); // Success
} else if (code == 401 || code == 403) {
// Not fully authorized for this action.
maybeAuthorized = false;
} else {
// Handle other response codes by logging them and throwing an
// exception.
console.error("Backend server error (%s): %s", code.toString(),
resp.getContentText("utf-8"));
throw ("Backend server error: " + code);
}
}
if (!maybeAuthorized) {
// Invoke the authorization flow using the default authorization
// prompt card.
CardService.newAuthorizationException()
.setAuthorizationUrl(service.getAuthorizationUrl())
.setResourceDisplayName("Display name to show to the user")
.throwException();
}
}
/**
* Create a new OAuth service to facilitate accessing an API.
* This example assumes there is a single service that the add-on needs to
* access. Its name is used when persisting the authorized token, so ensure
* it is unique within the scope of the property store. You must set the
* client secret and client ID, which are obtained when registering your
* add-on with the API.
*
* See the Apps Script OAuth2 Library documentation for more
* information:
* https://github.com/googlesamples/apps-script-oauth2#1-create-the-oauth2-service
*
* @return A configured OAuth2 service object.
*/
function getOAuthService() {
return OAuth2.createService('SERVICE_NAME')
.setAuthorizationBaseUrl('SERVICE_AUTH_URL')
.setTokenUrl('SERVICE_AUTH_TOKEN_URL')
.setClientId('CLIENT_ID')
.setClientSecret('CLIENT_SECRET')
.setScope('SERVICE_SCOPE_REQUESTS')
.setCallbackFunction('authCallback')
.setCache(CacheService.getUserCache())
.setPropertyStore(PropertiesService.getUserProperties());
}
/**
* Boilerplate code to determine if a request is authorized and returns
* a corresponding HTML message. When the user completes the OAuth2 flow
* on the service provider's website, this function is invoked from the
* service. In order for authorization to succeed you must make sure that
* the service knows how to call this function by setting the correct
* redirect URL.
*
* The redirect URL to enter is:
* https://script.google.com/macros/d/<Apps Script ID>/usercallback
*
* See the Apps Script OAuth2 Library documentation for more
* information:
* https://github.com/googlesamples/apps-script-oauth2#1-create-the-oauth2-service
*
* @param {Object} callbackRequest The request data received from the
* callback function. Pass it to the service's
* handleCallback() method to complete the
* authorization process.
* @return {HtmlOutput} a success or denied HTML message to display to
* the user.
*/
function authCallback(callbackRequest) {
var authorized = getOAuthService().handleCallback(callbackRequest);
if (authorized) {
return HtmlService.createHtmlOutput(
'Success!');
} else {
return HtmlService.createHtmlOutput('Denied');
}
}
/**
* Unauthorizes the non-Google service. This is useful for OAuth
* development/testing. Run this method (Run > resetOAuth in the script
* editor) to reset OAuth to re-prompt the user for OAuth.
*/
function resetOAuth() {
getOAuthService().reset();
}