使用OAuth 2.0&amp ;;从Google Chrome扩展程序获取辅助ID的验证令牌客户ID

时间:2016-12-20 16:25:56

标签: javascript google-chrome-extension oauth

我很擅长开发Chrome扩展程序,更具体地说是Chrome扩展程序中的用户身份验证部分。我正在关注Google Developer文档中的User Identity示例。

这个例子非常好用。我能够为chrome应用生成客户端ID,在我的案例Gmail API中添加API的范围。最后通过在identity中添加manifest.json权限来获取Auth Token,如下所示

"oauth2": {
    "client_id": "MY CLIENT ID",
    "scopes": [
      "https://www.googleapis.com/auth/gmail.readonly",
      "https://www.googleapis.com/auth/gmail.modify"
    ]
  }

我的app.js是一个content_script,它有以下代码。

chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
    /* With which I can use xhr requests to get data from Gmail API */
      console.log('Access Token : '+token);
});

现在我获得的这个令牌为我提供了我已登录chrome的用户的结果。含义假设我有一个UserA,电子邮件地址为user_a@gmail.com,我已将此日志用于Chrome浏览器。

问题

如何获取关联帐户或辅助帐户?例如,假设用户通过Chrome浏览器登录Gmail。是否可以访问当前登录的特定用户的Gmail API?

我在这里尝试过几件事。

gapi.auth.authorize({
            'client_id': CLIENT_ID,
            'scope': SCOPES.join(' '),
            'immediate': true
          }, 
          function(authResult){//do something});

在上面的场景中,客户端ID和范围是使用manifest.jsonchrome.runtime.getManifest();获取的。

  • 此方法使用google api的client.js并使用gapi变量。
  • 在这种情况下,我获取了我生成客户端ID的用户的访问令牌,甚至不是chrome应用程序用户。
  • 此外,当我打开隐身模式并访问此插件时,仍然会获得相同用户的访问令牌。

附加说明

我使用Web OAuth 2客户端ID尝试了相同的gapi.auth.authorize()。它工作得很好。我的意思是无论何时执行此授权,它都会获取当前登录用户的数据,或者它要求用户登录并进行身份验证的登录。如何在chrome扩展中实现相同的功能?如果我在这里错过了什么,请告诉我。

3 个答案:

答案 0 :(得分:2)

我最终处理的是这个(摘要):

  1. 在页面图层中,在加载时,我将堆栈中的消息发送到背景图层。
  2. 我使用launchWebAuthFlow()到https://accounts.google.com/o/oauth2/auth来获取该帐户的access_token。
  3. 我使用access_token对https://www.googleapis.com/oauth2/v4/token进行了AJAX调用以获取刷新令牌。
  4. 当用户通过右上角的头像按钮更改他们正在使用的帐户时,会再次触发此过程,因为它由onLoad针对扩展程序的页面层启动。

    上面描述遗漏的内容是缓存和错误处理,这些都是非常重要的。

答案 1 :(得分:1)

截至目前, 在Google Chrome stable(版本63)中使用支持的API 是不可能的。但是,在Dev频道中,很可能在将来的版本中,以下内容将是可能的:

chrome.identity.getAccounts(function(accounts) {
    // accounts is a list of accounts.
    chrome.identity.getAuthToken({ 'interactive': true, 'account': accounts[0] }, function(token) {
        /* With which i can use xhr requests to get data from gmail api */
          console.log('Access Token : '+token);
    });
});

请参阅the documentation for getAccounts()

编辑可能在此期间工作的东西是注册the onSigninChanged event

答案 2 :(得分:0)

http://developer.streak.com/2014/10/how-to-use-gmail-api-in-chrome-extension.html

是我最近在后台页面上实施的完整解决方案,可与Gmail API配合使用。

内容脚本调用弹出窗口授权使用生成的URL和简单服务器端点来存储刷新令牌。

$.oauthpopup = function (options) {
options.windowName = options.windowName || 'ConnectWithOAuth'; // should not include space for IE

var left = (screen.width / 2) - (800 / 2);
var top = (screen.height / 2) - (500 / 1.4);

options.windowOptions = options.windowOptions || 'location=0,status=0,width=800,height=500,left=' + left + ',top=' + top;
options.callback = options.callback || function () {
    window.location.reload();
};
var that = this;

debug('oauthpopup open separate _oauthWindow');
that._oauthWindow = window.open(options.path, options.windowName, options.windowOptions);
};

$.oauthpopup({
            path: 'https://accounts.google.com/o/oauth2/auth?' +
            'access_type=offline' +
            '&approval_prompt=force' +
            '&client_id=' + clientID +
            '&redirect_uri=' + callBackUrl +
            '&response_type=code' +
            '&scope=https://mail.google.com/ email profile' +
            '&state=' + login.timyoUUID +
            '&user_id=' + login.user_email,
            callback: function () {
                // do callback stuff
            },
        });

callBackUrl用于在服务器上存储刷新令牌。

以下是我为gapi的每个请求设置访问令牌的示例

export function setTokenForGAPI(accessToken) {
return getGAPIClient()
    .then(() => {
        const isSameToken = (currentAccessToken === accessToken);
        const noToken = ((accessToken === undefined) || (accessToken === ''));
        if (isSameToken || noToken) return;

        gapi.auth.setToken({
            access_token: accessToken,
        });

        currentAccessToken = accessToken;
    })
    .catch(function (e) {
        console.log('error in setTokenForGAPI', e);
    });
}
export function getEmailsByThreadIds(accessToken, ids) {
    return setTokenForGAPI(accessToken)
        .then(groupedThreadDetailsRequests(ids))
        .then(processEmailDetailsResponse);
}