google-apps-script - 在 Gmail 插件中获取 id 令牌以进行后端服务身份验证
问题描述
我正在使用 Google Apps 脚本创建 Gmail 插件的背景。通过这个插件,我想使用 REST 服务请求连接到我的后端服务器(非 Google 服务)。该请求必须得到授权。获得授权后,我可以向该服务器发出请求,以接收与数据库中该用户关联的数据。我已经在我的 web 应用程序中使用 Google 登录来登录后端服务 - 在前端,我在授权响应中收到 GoogleUser 对象内的 id_token。
问题
我需要这个 id_token 在通过 Gmail 插件连接到我的后端服务时登录它。但是,我找不到如何访问令牌的方法。
这项研究
我假设令牌必须通过 Apps 脚本中的 API 可用。
在 webapp 中,我使用 Google Auth API 收到 id_token,如下所示:
Promise.resolve(this.auth2.signIn())
.then((googleUser) => {
let user_token = googleUser.getAuthResponse().id_token; // this is the id_token I need in the Gmail plugin, too
// send the id_token to the backend service
...
};
在 Google Apps Script API 中,我只能找到 OAuth 令牌:
ScriptApp.getOAuthToken();
我假设令牌也可以存储在会话中。Google Apps 脚本 API 包含 Session 类,它本身包含 getActiveUser 方法,该方法返回 User 对象。然而,用户对象只包含用户的电子邮件地址,没有 id 令牌(或其他任何东西):
Session.getActiveUser().getEmail();
问题
有没有办法获得 id 令牌?
我是否选择了使用 Gmail 中已登录用户的数据登录后端服务器的正确方法?
解决方案
方法一:使用getIdentityToken()
获取有效用户的 OpenID Connect 身份令牌:
var idToken = ScriptApp.getIdentityToken();
var body = idToken.split('.')[1];
var decoded = Utilities.newBlob(Utilities.base64Decode(body)).getDataAsString();
var payload = JSON.parse(decoded);
var profileId = payload.sub;
Logger.log('Profile ID: ' + profileId);
方法 2:使用 Firebase 和getOAuthToken()
从 Apps Script 的 OAuth 令牌中获取 Google ID 令牌的步骤:
- 为您的 Apps 脚本项目启用 Identity Toolkit API。
- 在https://console.firebase.google.com/将新的 Firebase 项目添加到您现有的 Google Cloud Platform 项目
- 为平台创建 Firebase 应用:Web。
- 您将获得您的配置数据:
var firebaseConfig = {apiKey: YOUR_KEY, ...}
. - 在https://console.firebase.google.com/project/PROJECT_ID/authentication/providers为您的 Firebase 项目启用 Google 登录方法。
- 使用 Apps Script 函数获取当前用户的 ID Token:
function getGoogleIDToken()
{
// get your configuration from Firebase web app's settings
var firebaseConfig = {
apiKey: "***",
authDomain: "*.firebaseapp.com",
databaseURL: "https://*.firebaseio.com",
projectId: "***",
storageBucket: "***.appspot.com",
messagingSenderId: "*****",
appId: "***:web:***"
};
var res = UrlFetchApp.fetch('https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp?key='+firebaseConfig.apiKey, {
method: 'POST',
payload: JSON.stringify({
requestUri: 'https://'+firebaseConfig.authDomain,
postBody: 'access_token='+ScriptApp.getOAuthToken()+'&providerId=google.com',
returnSecureToken: true,
returnIdpCredential: true
}),
contentType: 'application/json',
muteHttpExceptions: true
});
var responseData = JSON.parse(res);
idToken = responseData.idToken;
Logger.log('Google ID Token: ');
Logger.log(idToken);
return idToken;
}
推荐阅读
- visual-studio-code - VS-Code 扩展,是注释中的插入符号吗?
- c# - 将 collectionView 组名称放在 Position.Start 上
- android - 如何在应用程序代码本身中使用 adb 命令卸载 android 应用程序?
- javascript - 如果我的网页未在任何选项卡中打开,则禁用通知
- ios - 羊皮纸的奇怪滚动错误
- c# - 使用 C# 在 ASP.NET MVC 中的 REST API 中具有额外 json 参数的多文件上传对象中的问题
- javascript - 命令 npm 生成与生命周期和启动应用程序相关的错误
- python - 计算年度回报的标准差
- python - 在 AzureML 上使用 Webservice.list 按名称选择模型
- angularjs - 如何在同一页面中有多个 angularjs 材料?