首页 > 解决方案 > 错误:未授予访问权限或已过期。从 PropertiesStore 中删除不记名令牌后

问题描述

我正在使用oauth2 库通过服务帐户和域范围委派进行身份验证以更改用户的签名:

function setSignature(email, signatureHtml) {  
var service = getDomWideDelegationService('Gmail: ', 
'https://www.googleapis.com/auth/gmail.settings.basic', email);

var resource = { signature: signatureHtml };

var requestBody                = {};
requestBody.headers            = {'Authorization': 'Bearer ' + service.getAccessToken()};
requestBody.method             = "PUT";
requestBody.contentType        = "application/json";
requestBody.payload            = JSON.stringify(resource);
requestBody.muteHttpExceptions = false;

var emailForUrl = encodeURIComponent(email);
var url = 'https://www.googleapis.com/gmail/v1/users/me/settings/sendAs/' + emailForUrl;
var setSignatureResponse = UrlFetchApp.fetch(url, requestBody);
}


function getDomWideDelegationService(serviceName, scope, email) {

  Logger.log('starting getDomainWideDelegationService for email: ' + email);

  var props = PropertiesService.getScriptProperties();
  const key = props.getProperty("OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY");
  const serviceaccount = props.getProperty("OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL");

  return OAuth2.createService(serviceName + email)
  // Set the endpoint URL.
  .setTokenUrl('https://accounts.google.com/o/oauth2/token')

  .setPrivateKey(key)
  .setIssuer(serviceaccount)
  .setSubject(email)
  .setPropertyStore(PropertiesService.getScriptProperties())
  .setScope(scope);
 }

这工作正常,直到我keyserviceaccount电子邮件从硬编码字符串替换PropertiesStore为上面所示的值。当我这样做时,我不小心删除了 PropertiesStore 中每个用户的 oauth2 条目。现在我收到以下错误

错误:未授予访问权限或已过期。在 Service_.getAccessToken(Service:454:11)

过了一会儿,我设法让它工作,但只有一个用户(即管理员用户)。对于所有其他用户,我仍然会收到此错误。

这是为什么?我认为每次都请求令牌,如果我从 PropertiesStore 中删除它应该没关系。

[编辑] 现在,在我使用 Userproperties 并将其改回以前的方式后,管理员帐户也不再工作了......

[EDIT2] 我现在可以指出问题所在。key显然从 PropertyStore读取是问题所在。当我替换这条线

const key = props.getProperty("OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY"); 使用它工作的键的硬编码值。

我将 ScriptProperty 中的值与正确的值进行了比较,它们是相同的。那么到底是什么?

标签: google-apps-scriptoauthgoogle-oauth

解决方案


经过长时间的反复试验,我发现了问题所在。ScriptProperty 中的密钥与实际密钥并非 100% 相同。

我在 Apps Script Project -> File -> Project Properties 中添加了密钥并创建了一个新行,然后用鼠标右键单击并点击Paste.

当我现在将硬编码的密钥与 ScriptProperty 中的密钥进行比较时,如下所示:

var hcKey  = 'srbvwrvwrvwrvrwvrewv';
var propKey = PropertiesService.getScriptProperty().getProperty('mykey');
var val = propKey.localeCompare(hcKey); // val is 1.0

看起来他们不一样。

当我之前通过 Apps 脚本存储密钥时,如下所示:

props.setProperty("mykey", 'srbvwrvwrvwrvrwvrewv');

有用。请注意,该值'srbvwrvwrvwrvrwvrewv'不是我刚刚在此处简化的实际键。

那么这是否意味着通过浏览器中的上下文菜单粘贴它,会添加一些隐藏字符,如空字符?

谁能解释一下?


推荐阅读