-->

通过图书馆OAuth2支援返回状态令牌无效或已过期。 请再试一次(OAuth2 support

2019-10-22 09:01发布

我有一个需要由各个用户在我的组织转换为PDF格式的电子表格。 为了做到这一点,我想使用的OAuth2( https://github.com/googlesamples/apps-script-oauth2 )。

当我在主电子表格嵌入脚本使用它,它的工作原理。 不过我想给的OAuth2代码移到一个单独的库一样,还会有很多的电子表格,将需要相同的功能。 当我使用这个库我收到消息“状态令牌无效或已过期,请重试。”

库代码:

var PROPERTY_KEY = "ExportPdfOauth2";

function initialStore() {
  setAuthenticationPackage_( {
    clientId : '10511......b43bu.apps.googleusercontent.com',
    clientSecret : 'WYUsq...-h_',
    projectKey : 'MxJ.......xOvW',
    scopes : ['https://spreadsheets.google.com/feeds/']
  });
}

function setAuthenticationPackage_(package) {
  PropertiesService.getScriptProperties().setProperty(PROPERTY_KEY, JSON.stringify(package));
}

function getAuthenticationPackage_() {
  var p = PropertiesService.getScriptProperties().getProperty(PROPERTY_KEY);
  return p ? JSON.parse(p) : {};
}

function getExportPdfService() {
  // Create a new service with the given name. The name will be used when
  // persisting the authorized token, so ensure it is unique within the
  // scope of the property store.

  var package = getAuthenticationPackage_();

  return OAuth2.createService('exportPdf')

      // Set the endpoint URLs, which are the same for all Google services.
      .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
      .setTokenUrl('https://accounts.google.com/o/oauth2/token')

      // Set the client ID and secret, from the Google Developers Console.
      .setClientId(package.clientId)
      .setClientSecret(package.clientSecret)

      // Set the project key of the script using this library.
      .setProjectKey(package.projectKey)

      // Set the name of the callback function in the script referenced
      // above that should be invoked to complete the OAuth flow.
      .setCallbackFunction('authCallback')

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getUserProperties())

      // Set the scopes to request (space-separated for Google services).
      .setScope(package.scopes)

      // Sets the login hint, which will prevent the account chooser screen
      // from being shown to users logged in with multiple accounts.
      .setParam('login_hint', Session.getActiveUser().getEmail())

      // Requests offline access.
      .setParam('access_type', 'offline')

      // Forces the approval prompt every time. This is useful for testing,
      // but not desirable in a production application.
      .setParam('approval_prompt', 'force');
}

function authCallback(request) {
  var user = Session.getActiveUser().getEmail();
  var exportPdfService = getExportPdfService();
  var isAuthorized = exportPdfService.handleCallback(request);
  if (isAuthorized) {
    return HtmlService.createHtmlOutput('Success');
  } else {
    return HtmlService.createHtmlOutput('Failure');
  }
}

function getExportPdfRequest() {
  var user = Session.getActiveUser().getEmail();
  var exportPdfService = getExportPdfService();
  if (!exportPdfService.hasAccess()) {
    var template = HtmlService.createTemplate('Authorisation required in order to enable conversion to pdf. You will need to perform the operation again once the authorisation is complete.')+
      '<br /><br />'+
      '<a href="<?= authorizationUrl ?>" target="_blank">'+
      'Authorise'+
      '</a>');
    template.authorizationUrl = exportPdfService.getAuthorizationUrl();
    var page = template.evaluate();
    SpreadsheetApp.getUi().showSidebar(page);
    return null;
  }

  var request = {
    headers: {
      Authorization: 'Bearer ' + exportPdfService.getAccessToken()
    }
  };

  return request;
}

该库由嵌入式脚本调用如下所示(请注意,我把这里的回调函数将回调库):

function test(){
  var id = 'ABCD.....'; // Spreadsheet to be converted to pdf
  var name = 'test.pdf';
  var domain = 'XXXXX';

  var pdfContent = spreadsheetToPDF(id,domain,name);
  if (pdfContent) DocsList.createFile(pdfContent);
}

// Convert spreadsheet to PDF file.
function spreadsheetToPDF(id,domain,name) {
  SpreadsheetApp.flush();

  var request = testPdfLib.getExportPdfRequest();
  if (!request) return null;

  //define the params URL to fetch
  var params = '?fitw=true&exportFormat=pdf&format=pdf&size=A4&portrait=true&sheetnames=false&printtitle=false&gridlines=false&pagenum=CENTER';
  var url = "https://docs.google.com/a/"+domain+"/spreadsheets/d/"+id+"/export"+params;

  //fetching file url
  var blob = UrlFetchApp.fetch(url, request);
  blob = blob.getBlob().setName(name);

  //return file
  return blob;
}

function authCallback(request) {
  testPdfLib.authCallback(request);
}

我也看了另一篇文章在如何正确构建状态令牌回调网址托管库? 但还是无法弄清楚我在做什么错了,因为我已经在主调用脚本提供的回调函数。 在开发者控制台我的重定向URI点到库中。 我试图把它指向主脚本,但我得到了相同的结果(虽然我不喜欢这样做,因为脚本会被许多用户所复制就不可能创建一个新的客户端ID为的每个实例调用脚本)。

感谢任何帮助!

文章来源: OAuth2 support through library returns The state token is invalid or has expired. Please try again