google-apps-script - 错误:未授予访问权限或已过期。从 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);
}
这工作正常,直到我key
将serviceaccount
电子邮件从硬编码字符串替换PropertiesStore
为上面所示的值。当我这样做时,我不小心删除了 PropertiesStore 中每个用户的 oauth2 条目。现在我收到以下错误
错误:未授予访问权限或已过期。在 Service_.getAccessToken(Service:454:11)
过了一会儿,我设法让它工作,但只有一个用户(即管理员用户)。对于所有其他用户,我仍然会收到此错误。
这是为什么?我认为每次都请求令牌,如果我从 PropertiesStore 中删除它应该没关系。
[编辑] 现在,在我使用 Userproperties 并将其改回以前的方式后,管理员帐户也不再工作了......
[EDIT2]
我现在可以指出问题所在。key
显然从 PropertyStore读取是问题所在。当我替换这条线
const key = props.getProperty("OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY");
使用它工作的键的硬编码值。
我将 ScriptProperty 中的值与正确的值进行了比较,它们是相同的。那么到底是什么?
解决方案
经过长时间的反复试验,我发现了问题所在。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'
不是我刚刚在此处简化的实际键。
那么这是否意味着通过浏览器中的上下文菜单粘贴它,会添加一些隐藏字符,如空字符?
谁能解释一下?
推荐阅读
- python - 部署到服务器后 Django 语言环境不工作 [已修复]
- wcf - 将 Membership 的使用转换为可在 .NET Core 中用于 WCF 服务调用的东西
- amazon-cognito - Cognito 用户池中的 SMS MFA 状态是通过调用 setPreferredMFA 设置的还是其他的?
- wordpress - Wordpress - 从帖子中隐藏类别
- sql - Oracle SQL:为列中的每个值创建一个新行,其中更多值用逗号分隔
- assembly - Raspberry Pi 4 的正确 .cpu、.fpu 程序集条目是什么
- flutter - Flutter 小部件未正确交换其位置
- python - 如何单击 selenium python 中的保存按钮?不断收到 StaleElementReferenceException
- php - Nested function inside While loop - PHP
- beautifulsoup - Python bs4 提取正确的表格内容