1

I've deployed a protected web app, and I'd like to trigger it without logging in each time: enter image description here

I'd like to access the web app URL without logging in: enter image description here

Based on this document, it's not possible without logging in from browser: https://github.com/tanaikech/taking-advantage-of-Web-Apps-with-google-apps-script/blob/master/README.md

If the script of Web Apps uses some scopes, client users have to authorize the scopes by own browser.

I'm assuming scopes means the web app is protected.

I've tried this: https://github.com/gsuitedevs/apps-script-oauth2/blob/master/samples/GoogleServiceAccount.gs but it asks for "request access"

https://i.imgur.com/eRUaXlh.png

If I click on request access, then it shows me this: enter image description here

At this point, I'm thinking it's not possible to setup a service account with scope to trigger a protected deployed web app without authenticating through a browser each time. Can anyone confirm this?

My assumption is that the web app scope is https://www.googleapis.com/auth/drive since it has access to all drive's files.

Update: (What I tried but didn't work)

I matched the scope from the script:

enter image description here

To the service account:

enter image description here

The blurred area above is the client id i got from:

enter image description here

I've generated the access token using this script:

function accessTokens(){
 var private_key = "-----BEGIN PRIVATE KEY-----*****\n-----END PRIVATE KEY-----\n"; // private_key of JSON file retrieved by creating Service Account
var client_email = "****@****.iam.gserviceaccount.com"; // client_email of JSON file retrieved by creating Service Account
var scopes = ["https://www.googleapis.com/auth/documents","https://www.googleapis.com/auth/forms","https://www.googleapis.com/auth/script.external_request","https://www.googleapis.com/auth/spreadsheets","https://www.googleapis.com/auth/userinfo.email"]; // Scopes


var url = "https://www.googleapis.com/oauth2/v3/token";
var header = {
  alg: "RS256",
  typ: "JWT",
};
var now = Math.floor(Date.now() / 1000);
var claim = {
  iss: client_email,
  scope: scopes.join(" "),
  aud: url,
  exp: (now + 3600).toString(),
  iat: now.toString(),
};
var signature = Utilities.base64Encode(JSON.stringify(header)) + "." + Utilities.base64Encode(JSON.stringify(claim));
var jwt = signature + "." + Utilities.base64Encode(Utilities.computeRsaSha256Signature(signature, private_key));

var params = {
  method: "post",
  payload: {
    assertion: jwt,
    grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
  },
};
var res = UrlFetchApp.fetch(url, params).getContentText();
Logger.log(res); 
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getSheetByName("Sheet1");
  sheet.getRange(1, 3).setValue(JSON.parse(res)['access_token']);
}

And still has the same error, it asks for request access.

10
  • When you created your service account, did you provide domain wide authority delegation? Commented Feb 20, 2019 at 9:05
  • I did yesterday, still no luck: i.imgur.com/nVqGgjV.png Commented Feb 20, 2019 at 15:38
  • I think this is particularly tricky because I have a gsuite business account. Commented Feb 20, 2019 at 16:50
  • I'm a bit confused, why do you need to access it via the Web-App URL if you don't want to use a browser, is there a reason you can't use a regular Apps Script Trigger to trigger the relevant code without accessing the web interface? Commented Feb 20, 2019 at 17:03
  • 1
    @TheMaster figured it out! needed to adjust the script a bit and missed a few things. Thanks for the link. Commented Feb 20, 2019 at 22:27

1 Answer 1

1

After a couple days into this, I've figured it out (with help of course).

  1. Get the scope from your deployed web app script: File > Project Properties > Scopes
  2. Add the scope along with https://www.googleapis.com/auth/drive in page Manage API client access https://admin.google.com/AdminHome?chromeless=1#OGX:ManageOauthClients (use comma delimited to add multiple scopes: http...,http..., etc.)
  3. For the client name, get the client id from the service account page in your admin console: https://console.developers.google.com
  4. Deploy your script Publish > Deploy as Web App
  5. After generating access token(instruction below), append the access token with your deployed web app url &access_token=YOURTOKENHERE

Use this script with a google sheet, it will generate the access_token in cell A1 of Sheet1 (Replace the 4 variables with the info relevant to you):

function accessTokens(){
 var private_key = "-----BEGIN PRIVATE KEY-----n-----END PRIVATE KEY-----\n"; // private_key of JSON file retrieved by creating Service Account
var client_email = "*****@****.iam.gserviceaccount.com"; // client_email of JSON file retrieved by creating Service Account
var scopes = ["https://www.googleapis.com/auth/documents","https://www.googleapis.com/auth/forms","https://www.googleapis.com/auth/script.external_request","https://www.googleapis.com/auth/spreadsheets","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/drive"]; // Scopes
var impersonate_email = "" //impersonate email

var url = "https://www.googleapis.com/oauth2/v4/token";
var header = {
  alg: "RS256",
  typ: "JWT",
};
var now = Math.floor(Date.now() / 1000);
var claim = {
  iss: client_email,
  sub: impersonate_email,
  scope: scopes.join(" "),
  aud: url,
  exp: (now + 3600).toString(),
  iat: now.toString(),
};
var signature = Utilities.base64Encode(JSON.stringify(header)) + "." + Utilities.base64Encode(JSON.stringify(claim));
var jwt = signature + "." + Utilities.base64Encode(Utilities.computeRsaSha256Signature(signature, private_key));

var params = {
  method: "post",
  payload: {
    assertion: jwt,
    grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
  },
};
var res = UrlFetchApp.fetch(url, params).getContentText();
Logger.log(res); 
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getSheetByName("Sheet1");
  sheet.getRange(1, 1).setValue(JSON.parse(res)['access_token']);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.