# OAuth2 library in Apps Script [[TOC]] De OAuth2 library van Google Workspace is de standaardmanier om vanuit Apps Script veilig te koppelen met externe diensten die OAuth2 gebruiken, denk aan Salesforce, GitHub, Slack of Microsoft Graph. De library regelt de volledige token-flow, inclusief het automatisch vernieuwen van verlopen tokens. ## OAuth2 library installeren De OAuth2 library is een open-source Apps Script library die je via de library-manager toevoegt aan je project. :::howto title="Library toevoegen aan je project" 1. Open je Apps Script project op `script.google.com`. 2. Klik op **Libraries** (het plus-icoon naast Libraries in de zijbalk). 3. Voer de script-ID in: `1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF`. 4. Klik op **Look up** en selecteer de nieuwste versie. 5. Laat de identifier op `OAuth2` staan en klik op **Add**. ::: Controleer daarna of de library beschikbaar is: ```javascript function testLibraryBeschikbaar() { Logger.log(typeof OAuth2); } ``` ## OAuth2 service aanmaken Een service bundelt alle instellingen van een OAuth2-koppeling: de autorisatie-URL, token-URL, client-gegevens en scopes. Bewaar de client-ID en het secret altijd in Script Properties, nooit hardcoded in je code. ```javascript function getOAuth2Service() { return OAuth2.createService('ExterneSaasDienst') .setAuthorizationBaseUrl('https://accounts.externe-dienst.nl/oauth/authorize') .setTokenUrl('https://accounts.externe-dienst.nl/oauth/token') .setClientId(PropertiesService.getScriptProperties().getProperty('OAUTH_CLIENT_ID')) .setClientSecret(PropertiesService.getScriptProperties().getProperty('OAUTH_CLIENT_SECRET')) .setCallbackFunction('authCallback') .setPropertyStore(PropertiesService.getUserProperties()) .setScope('read write') .setParam('access_type', 'offline'); } ``` :::warn title="Bewaar je client secret veilig" Zet `OAUTH_CLIENT_ID` en `OAUTH_CLIENT_SECRET` via **Project Settings, Script Properties** in de editor. Deze waarden horen niet in je broncode of versiebeheer thuis. Gebruik `getUserProperties()` als propertyStore zodat elke gebruiker een eigen token krijgt en niemand andermans toegang kan hergebruiken. ::: ## Autorisatieflow starten De gebruiker moet eenmalig de toegang goedkeuren. Je genereert een autorisatie-URL en toont die in een dialoog. Na goedkeuring stuurt de externe dienst de gebruiker terug naar je callback-functie. ```javascript function autoriseer() { const service = getOAuth2Service(); if (service.hasAccess()) { Logger.log('Al geautoriseerd'); return; } const authUrl = service.getAuthorizationUrl(); Logger.log('Ga naar deze URL om te autoriseren: ' + authUrl); const template = HtmlService.createTemplate( 'Klik hier om te autoriseren' ); template.authUrl = authUrl; const ui = SpreadsheetApp.getUi(); ui.showModalDialog(template.evaluate().setWidth(400).setHeight(100), 'Autorisatie vereist'); } function authCallback(request) { const service = getOAuth2Service(); const isAuthorized = service.handleCallback(request); if (isAuthorized) { return HtmlService.createHtmlOutput('Autorisatie geslaagd. Je kunt dit venster sluiten.'); } else { return HtmlService.createHtmlOutput('Autorisatie mislukt.'); } } ``` :::info title="Callback-URL registreren bij de externe dienst" De callback-URL die je bij de externe dienst moet registreren heeft de vorm `https://script.google.com/macros/d/SCRIPT_ID/usercallback`. Vervang `SCRIPT_ID` door je eigen script-ID. Die vind je in de editor onder **Project Settings**. Moet de URL exact overeenkomen, anders weigert de provider de redirect. ::: ## API-calls uitvoeren met OAuth2-token Zodra de service toegang heeft, voeg je het access token toe als `Authorization`-header in je `UrlFetchApp`-aanroep. Vang een `401` op om een verlopen of ingetrokken token netjes af te handelen. ```javascript function haalBeschermdeData() { const service = getOAuth2Service(); if (!service.hasAccess()) { Logger.log('Niet geautoriseerd. Roep autoriseer() aan.'); return; } const token = service.getAccessToken(); const response = UrlFetchApp.fetch('https://api.externe-dienst.nl/mijn-data', { headers: { 'Authorization': `Bearer ${token}`, 'Accept': 'application/json', }, muteHttpExceptions: true, }); if (response.getResponseCode() === 401) { service.reset(); Logger.log('Token verlopen of ingetrokken, vraag opnieuw autorisatie aan'); return; } return JSON.parse(response.getContentText()); } ``` ## Token vernieuwen en toegang intrekken De library vernieuwt access tokens automatisch zolang er een geldig refresh token is. Je hoeft dat dus niet zelf te doen. Wel handig zijn een functie om de autorisatie te wissen en een functie om de status te controleren. ```javascript function verwijderAutorisatie() { const service = getOAuth2Service(); service.reset(); Logger.log('Autorisatie verwijderd'); } function controleerAutorisatie() { const service = getOAuth2Service(); Logger.log(`Heeft toegang: ${service.hasAccess()}`); if (service.hasAccess()) { const token = service.getAccessToken(); Logger.log(`Token begint met: ${token.substring(0, 10)}...`); } } ``` ## Google OAuth2 voor Google APIs Voor Google-services heb je deze library meestal niet nodig, omdat Apps Script de ingebouwde autorisatie regelt. Wil je toch met een eigen Google Cloud-project en specifieke scopes werken (bijvoorbeeld om delegated toegang te beheren), dan configureer je de service zo: ```javascript function getGoogleApiService() { return OAuth2.createService('GoogleCalendarApi') .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth') .setTokenUrl('https://accounts.google.com/o/oauth2/token') .setClientId(PropertiesService.getScriptProperties().getProperty('GOOGLE_CLIENT_ID')) .setClientSecret(PropertiesService.getScriptProperties().getProperty('GOOGLE_CLIENT_SECRET')) .setCallbackFunction('authCallback') .setPropertyStore(PropertiesService.getUserProperties()) .setScope('https://www.googleapis.com/auth/calendar.readonly') .setParam('access_type', 'offline') .setParam('prompt', 'consent'); } ``` :::tip title="Vraag minimale scopes aan" Vraag alleen de scopes aan die je echt nodig hebt, bijvoorbeeld `calendar.readonly` in plaats van volledige `calendar`-toegang. Minder scopes betekent minder risico bij een gelekt token en een korter goedkeuringsscherm voor je gebruikers. ::: ## Praktijkvoorbeeld: Salesforce verbinden Een veelvoorkomende koppeling is Salesforce. De stappen zijn representatief voor vrijwel elke OAuth2-dienst. :::howto title="Salesforce koppelen via OAuth2" 1. Maak een **Connected App** aan in Salesforce en stel daar je callback-URL in (`https://script.google.com/macros/d/SCRIPT_ID/usercallback`). 2. Sla de Client ID en het Secret op in Script Properties via **Project Settings**. 3. Configureer de OAuth2 service met de Salesforce autorisatie-URL en token-URL. 4. Stuur de gebruiker naar `service.getAuthorizationUrl()` voor de eerste autorisatie. 5. Verwerk de terugkoppeling in `authCallback()` met `service.handleCallback(request)`. 6. Gebruik het token in `UrlFetchApp`-aanroepen naar de Salesforce REST API. ::: :::faq ### Wanneer gebruik ik de OAuth2 library en wanneer de ingebouwde autorisatie? De ingebouwde autorisatie van Apps Script werkt alleen voor Google-services. De OAuth2 library gebruik je voor niet-Google OAuth2-diensten zoals Salesforce, GitHub, Slack of Microsoft Graph. ### Waar worden de tokens opgeslagen? In de Properties Store die je instelt via `setPropertyStore()`. Gebruik `getUserProperties()` voor tokens per gebruiker, zodat niemand andermans toegang kan hergebruiken. `getScriptProperties()` deelt het token tussen alle gebruikers en is alleen geschikt voor een service-account-achtige opzet. ### Hoe verleng ik een verlopen access token? Dat hoeft niet handmatig. De library verlengt access tokens automatisch via het refresh token, mits je `access_type=offline` hebt aangevraagd. Is ook het refresh token verlopen of ingetrokken, roep dan `service.reset()` aan en laat de gebruiker opnieuw autoriseren. ### Kan ik de PKCE-flow gebruiken voor public clients? Ja, de library ondersteunt PKCE voor diensten die dat vereisen, bijvoorbeeld de X-API. De configuratie verschilt per versie, dus raadpleeg de samples en de CHANGELOG in de officiele repository (`github.com/googleworkspace/apps-script-oauth2`) voor de exacte aanpak in jouw versie. ### Welke versie van de library moet ik kiezen? Selecteer in de library-manager de hoogst beschikbare versie. De library is volwassen en stabiel, en een nieuwere versie bevat fixes en ondersteuning voor extra flows zoals PKCE. ### Wat doe ik als de autorisatie steeds mislukt? Controleer eerst of de geregistreerde callback-URL exact overeenkomt met `https://script.google.com/macros/d/SCRIPT_ID/usercallback`. Controleer daarna of de Client ID en het Secret kloppen en of de aangevraagde scopes zijn toegestaan bij de externe dienst. ::: De OAuth2 library maakt het mogelijk om Apps Script te integreren met praktisch elke OAuth2-beveiligde dienst. Ze abstraheert de complexe token-flow en zorgt voor automatische vernieuwing, zodat jij je kunt richten op de API-aanroepen zelf.