首页 > 解决方案 > 在 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 中已登录用户的数据登录后端服务器的正确方法?

标签: google-apps-scriptgoogle-apigoogle-oauthgoogle-openidgmail-addons

解决方案


方法一:使用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 令牌的步骤:

  1. 为您的 Apps 脚本项目启用 Identity Toolkit API。
  2. 在https://console.firebase.google.com/将新的 Firebase 项目添加到您现有的 Google Cloud Platform 项目
  3. 为平台创建 Firebase 应用:Web
  4. 您将获得您的配置数据:var firebaseConfig = {apiKey: YOUR_KEY, ...}.
  5. 在https://console.firebase.google.com/project/PROJECT_ID/authentication/providers为您的 Firebase 项目启用 Google 登录方法。
  6. 使用 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;
}

瑞尔·诺特曼致敬


推荐阅读