Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obtain an id token in the Gmail add-on for a backend service authentication

The background
I'm using the Google Apps Script to create a Gmail Add-on. Via this plugin, I would like to connect to my backend server (a non-Google service) using a REST service request. The request has to be authorised. When authorised, I could then make requests to that server to receive data associated with that user in the database. I'm already using Google sign-in in my webapp to sign in to the backend service - at the front end, I receive the id_token inside of the GoogleUser object in the authorisation response.

The problem
I need this id_token to log in to my backend service when connecting to it via the Gmail plugin. However, I couldn't find a way how to access the token.

The research
I would assume the token must be available through the API in the Apps Script.
In the webapp, I receive the id_token using the Google Auth API like this:

Promise.resolve(this.auth2.signIn())
        .then((googleUser) => {
            let user_token = googleUser.getAuthResponse().id_token; // this is the id_token I need in the Gmail plugin, too

            // send the id_token to the backend service
            ...
        };

In the Google Apps Script API I could only find the OAuth token:

ScriptApp.getOAuthToken();

I assumed the token could also be stored in the session. The Google Apps Script API contains the Session class and that itself contains the getActiveUser method, which returns the User object. The User object, however, only contains the user's email address, no id token (or anything else for that matter):

Session.getActiveUser().getEmail();


The question(s)
Is there a way to obtain the id token?
Am I choosing the right approach to logging in to the backend server using the data of the signed-in user in the Gmail?

like image 604
Patrik Chynoranský Avatar asked Sep 18 '18 13:09

Patrik Chynoranský


2 Answers

Method 1: use getIdentityToken()

Gets an OpenID Connect identity token for the effective user:

var idToken = ScriptApp.getIdentityToken();
var body = idToken.split('.')[1];
var decoded = Utilities.newBlob(Utilities.base64Decode(body)).getDataAsString();
var payload = JSON.parse(decoded);
var profileId = payload.sub;
Logger.log('Profile ID: ' + profileId);

Method 2: use Firebase and getOAuthToken()

Steps to get Google ID Token from Apps Script's OAuth token:

  1. Enable Identity Toolkit API for your Apps Script project.
  2. Add new Firebase project to your existing Google Cloud Platform project at https://console.firebase.google.com/
  3. Create Firebase app for platform: Web.
  4. You will get your config data: var firebaseConfig = {apiKey: YOUR_KEY, ...}.
  5. Enable Google sign-in method for your Firebase project at https://console.firebase.google.com/project/PROJECT_ID/authentication/providers.
  6. Use Apps Script function to get ID Token for current user:

function getGoogleIDToken()
{
    // get your configuration from Firebase web app's settings
    var firebaseConfig = {
        apiKey: "***",
        authDomain: "*.firebaseapp.com",
        databaseURL: "https://*.firebaseio.com",
        projectId: "***",
        storageBucket: "***.appspot.com",
        messagingSenderId: "*****",
        appId: "***:web:***"
    };

    var res = UrlFetchApp.fetch('https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp?key='+firebaseConfig.apiKey, {
        method: 'POST',
        payload: JSON.stringify({
            requestUri: 'https://'+firebaseConfig.authDomain,
            postBody: 'access_token='+ScriptApp.getOAuthToken()+'&providerId=google.com',
            returnSecureToken: true,
            returnIdpCredential: true
        }),
        contentType: 'application/json',
        muteHttpExceptions: true
    });

    var responseData = JSON.parse(res);

    idToken = responseData.idToken;

    Logger.log('Google ID Token: ');
    Logger.log(idToken);

    return idToken;
}

Kudos to Riël Notermans

like image 66
Kos Avatar answered Oct 12 '22 16:10

Kos


You should enable oAuth scopes, https://developers.google.com/apps-script/concepts/scopes

like image 30
Macondo Avatar answered Oct 12 '22 16:10

Macondo