다른 Apps Script 프로젝트에서 Apps Script 웹 앱을 실행할 때 프로그래밍 방식으로 인증하는 방법

Nov 16 2020

Apps Script를 처음 사용하며 한 계정에서 다른 계정을 사용하여 스크립트를 실행 / 트리거하는 기본 사항을 이해하려고합니다. 주의 사항 : 사용자가 액세스하는 사용자에게 런타임을 할당하기 위해 스크립트를 소유 한 사용자 대신 스크립트에 액세스하는 사용자로 스크립트를 실행하고 싶습니다.

그러나 다음과 같은 문제가 있습니다.


공유가있는 스프레드 시트를 링크가있는 모든 사용자가 편집 할 수있는 테스트로 시작하여 스크립트 프로젝트 페이지에서 다음 코드를 편집 할 수 있습니다.

function doPost(e){
  var sheet = SpreadsheetApp.openById('1tWV6ELJEGkWkSXvdf9kQemvH-tDVTx0od4JHht2ZBeU');
  var tab = sheet.getSheetByName('ref');
  tab.getRange(1,1).setValue(new Date());
  return ContentService.createTextOutput(0)
}

function doGet(e){
  return doPost(e)
}

프로젝트를 사용자 액세스로 실행 설정하고 누구나 액세스 할 수있는 웹 앱으로 게시했습니다. 브라우저에 다음 링크를 입력하면 A1 셀에 현재 시간과 의도 한대로 '0'이 표시된 페이지가 수동으로 채워집니다.

https://script.google.com/macros/s/AKfycbwNhYg1BRKi38pNf_z0peGuYt6gsqvauCvo-eiGgCYJJk4QDpjm/exec

IF I이 링크를 입력 여전히 테스트 스프레드 시트를 생성 한 계정으로 로그인 한 상태.

GSuite에 로그인하지 않고 다른 브라우저로 링크를 입력하면 로그인이 필요합니다. 결국 웹 앱 배포별로 스크립트를 실행하려면 G Suite 계정이 필요합니다.

그러나 다른 GSuite 계정 및 Apps Script 프로젝트를 사용하여 스크립트를 트리거하려고 시도했을 때 여전히 로그인 페이지 및 기타 문제가 발생했습니다. 아웃

function test1(){
  const scriptURL='https://script.google.com/macros/s/AKfycbwNhYg1BRKi38pNf_z0peGuYt6gsqvauCvo-eiGgCYJJk4QDpjm/exec';  
  var response = UrlFetchApp.fetch(scriptURL)
  Logger.log(response.getContentText())
}

function test2(){
  const scriptURL='https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec';  
  var response = UrlFetchApp.fetch(scriptURL, {
    method:'POST',
    payload:'nothing'
  });  
  Logger.log(response.getContentText())
}

function test3() {
  var sheet = SpreadsheetApp.openById('AKfycbwNhYg1BRKi38pNf_z0peGuYt6gsqvauCvo-eiGgCYJJk4QDpjm');
  Logger.log(sheet.getName());
}

function test4() {
  var token = ScriptApp.getOAuthToken();
  const scriptURL='https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec';  
  var response = UrlFetchApp.fetch(scriptURL, {
    headers: {Authorization:'Bearer '+ token},
    method:'GET',
    payload:'nothing'
  });  
  Logger.log(response.getContentText())
}

test1() Log에서 다음으로 시작하는 긴 텍스트 본문을 생성합니다.

Logging output too large. Truncating output. 
<!DOCTYPE html>
<html lang="en">
  <head>
  <meta charset="utf-8">
  <meta content="width=300, initial-scale=1" name="viewport">
  <meta name="google-site-verification" content="LrdTUW9psUAMbh4Ia074-BPEVmcpBxF6Gwf0MSgQXZs">
  <title>Sign in - Google Accounts</title>
  <style>

오류를 test2()반환합니다.

Exception: Request failed for https://script.google.com returned code 401. Truncated server response: <!DOCTYPE html><html lang="en"><head><meta name="description" content="Web word processing, presentations and spreadsheets"><meta name="viewport" c... (use muteHttpExceptions option to examine full response)
    at test2(Code:23:30)

doPost(e)A1 셀이 업데이트되지 않았으므로 두 테스트 모두에서 스크립트를 트리거 하지 않았습니다.

test1()로그인 페이지가있는 것 같습니다. 그러나 동시에 test1()로그인 G Suite 계정을 통해 실행됩니다.

test3()문제의 Google 스프레드 시트 파일에 액세스 할 수 있다는 점도 주목할 가치가 있습니다 . 나는 또한 ScriptApp.getOAuthToken()왜 안되기 때문에 전화를 시도했다 . test4()와 동일한 응답이 있습니다 test1().

에서 발생한 오류로 어디에서 진단을 시작해야할지 모르겠습니다 test2().


로그인 페이지를 탐색하려면 어떻게합니까?

특히 문제의 Google 스프레드 시트에 대한 액세스 권한이있는 다른 GSuite 계정에서 스크립트에 액세스 할 수 있도록하고 스프레드 시트를 소유 한 사용자가 아닌 사용자 액세스에 의해 실행되도록하는 방법이 있습니까?

POST 버전에서 내가 뭘 잘못하고 있니?

어떤 도움이라도 감사드립니다!

답변

4 Tanaike Nov 17 2020 at 06:49

귀하의 질문에서 귀하의 상황을 다음과 같이 이해했습니다.

  • Web Apps의 스크립트는의 스프레드 시트의 컨테이너 바인딩 스크립트에 저장 1tWV6ELJEGkWkSXvdf9kQemvH-tDVTx0od4JHht2ZBeU됩니다.
  • 스프레드 시트는 다음과 같이 공유 Anyone with the linkeditor.
  • Web Apps는 Execute the app as: User accessing the web apps및 로 배포됩니다 Who has access to the app: Anyone.

이 답변은 위의 이해를 가정합니다. 그러니 제 이해가 틀렸을 때 알려주세요.

수정 지점 :

  • 에서 UrlFetchApp사용시 사용시 payload:'nothing'에도 POST 방식으로 요청한다 method:'GET'. 조심하세요.
  • Web Apps 스크립트에서 https://www.googleapis.com/auth/spreadsheets. 이 경우 먼저 자신의 브라우저 (각 사용자의 브라우저)에서 범위를 인증해야합니다. 이를 수행하지 않으면 클라이언트 측 범위의 스크립트 및 액세스 토큰이 정확 Authorization needed하더라도 오류가 발생합니다. 조심하세요. 이것이 현재 사양 인 것 같습니다.
  • 클라이언트 측 의 전체 스크립트 ( test1~ test4)가 질문의 스크립트 인 경우 범위는 https://www.googleapis.com/auth/script.external_requesthttps://www.googleapis.com/auth/spreadsheets입니다. Web Apps를 요청하기에 범위가 충분하지 않다고 생각합니다. 이 경우 예를 들어 // DriveApp.getFiles()스크립트 편집기에 추가하십시오 . 이에 https://www.googleapis.com/auth/drive.readonly따라 스크립트 편집기에 의해 범위 가 자동으로 추가되며이 범위는 Web Apps에 요청하는 데 사용할 수 있습니다. 또한 범위를 사용할 수 있습니다 https://www.googleapis.com/auth/drive.
    • https://www.googleapis.com/auth/script.external_request및 범위의 경우 https://www.googleapis.com/auth/spreadsheets오류가 Unauthorized발생합니다.

위의 사항이 귀하의 상황에 반영되면 다음과 같이됩니다.

용법:

1. Web Apps 쪽을 준비합니다. (서버 측)

이 경우 귀하의 설정을 사용할 수 있다고 생각합니다. 만일을 대비하여 Web Apps를 새 버전으로 재배포하십시오. 그리고 Web Apps의 URL을 다시 확인하십시오.

2. 클라이언트 측을 준비합니다.

  1. https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec자신의 브라우저 (사용자측) 를 사용하여 접속하여주십시오 . 그리고 Web Apps의 범위를 승인 해주십시오.

  2. test4()다음과 같이 스크립트 수정을 제안하고 싶습니다 .

     function test4() {
       var token = ScriptApp.getOAuthToken();
       const scriptURL='https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec';  
       var response = UrlFetchApp.fetch(scriptURL, {
         headers: {Authorization:'Bearer '+ token},
         method: 'GET',
     //    payload:'nothing',
         muteHttpExceptions: true
       });  
       Logger.log(response.getContentText())
    
       // DriveApp.getFiles()  // This is used for adding a scope of https://www.googleapis.com/auth/drive.readonly. This is used for requesting to Web Apps.
     }
    
  3. 실행하십시오 test4(). 이로써 0Web Apps에서 반환되며 로그에서 확인할 수 있습니다.

참조 :

  • Google Apps Script로 웹 애플리케이션 활용
  • fetch (URL, 매개 변수)