9
votes

I am facing HTTP 401 errors while trying to call a deployed Apps Script (as a web app, accessible to "anyone") from a second GAS with UrlFetch and a bearer in authorization header. The scripts were working fine for months until around two weeks ago. Here are two small scripts to reproduce the error.

Script A - Deployed as a web app, accessible to "Anyone".

function doGet(e) {
  var params = e.parameter.params;
  console.info("Parameters : " + JSON.stringify(e.parameter));
  return ContentService.createTextOutput("Success");
}

Script B - Calling the script A via UrlFetch

function callURL() {
  var param = {
    method      : "get",
    headers     : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
    followRedirects : true,
    muteHttpExceptions:true,
  };
  var url = "https://script.google.com/macros/s/<script_A_deployed_url>/exec?param1=test";
  var resp = UrlFetchApp.fetch(url,param);
  if(resp.getContentText() != "Success"){
    console.info(resp.getContentText());
    throw resp.getContentText();
  }
}
2
Did you tried doing the same using Postman/etc ? - Umair Mohammad
Yes, I managed to reproduce this behavior using Insomnia. - Q_C
What's the exact error message ? Earlier same setup & code was workin ? - Umair Mohammad
401 Unauthorized. Yes, we have been using this authentication mechanism since several months without any issue. - Q_C
Try publishing app with public access (Anyopne, even anonymous) see if that works, if that works, then make sure header is coming properly - Umair Mohammad

2 Answers

8
votes

Can you confirm the following points again?

  1. For the client side, are there some functions except for your script of the client side in the project? If there is only the script in the project, the scope for accessing to Web Apps is not enough. The scopes for Drive API are required to be included in the scope of access token.
    • You can see the current scopes at File -> Project properties -> Scopes.
    • For example, those are the following scopes.
      • https://www.googleapis.com/auth/drive.readonly
      • https://www.googleapis.com/auth/drive.files
      • https://www.googleapis.com/auth/drive
  2. In my log, when Who has access to the app: is installed as Anyone, I confirmed that from April 11, 2018, it is required to be shared the project to access to Web Apps. This might be due to the update of Google.
    • Please share the project of Web Apps with users and try again.
  3. For the Web Apps server side, if you set User accessing the web app for Execute the app as:, please authorize the scopes using own browser. This authorization is required to do only one time.

If these were not useful for your situation, I'm sorry.

6
votes

Tanaike pointed me in the right direction. Apparently, some internal rules recently changed in the authentication mechanism for Apps Script deployed as a web app. For B script, the default scope with UrlFetch is https://www.googleapis.com/auth/script.external_request, but it looks like we now need at least read access to A script, which means we also need Drive scopes. In order to achieve that, you can for example have this function in B script to authorize them.

function setScope() {
  DriveApp.getRootFolder();
}