繁体   English   中英

将 Google API 凭证与应用程序一起分发是否安全?

[英]Is it safe to distribute Google API credentials with apps?

我正在尝试制作一个简单的桌面 email 阅读器(带电子),在可以翻阅的小卡片上显示用户的电子邮件。 没什么,这就是为什么我不想为它设置一个完整的远程服务器系统。 我按照Google 的 NodeJS 快速入门指南中的说明开始操作。 这包括将我的 Google API 凭据保存到应用程序中的文件中。 登录后,令牌将保存到磁盘。 如果不存在这样的令牌,它将在浏览器中打开一个登录页面,重定向到127.0.0.1:3000/authorize (那里运行的快速应用程序保存令牌)。 它可以工作并且不需要我想要的远程服务器。

我的问题是,与我的应用程序一起分发credentials.json文件(包含 client_id、client_secret、project_id)是否安全? 潜在的安全问题是什么? 如果这不合适,使我的应用程序可安全分发的最简单的替代方法是什么?

编辑

我查看了 Google 的文档,发现了这个

该过程会产生一个客户端 ID,在某些情况下,还会产生一个客户端密码,您可以将其嵌入应用程序的源代码中。 (在这种情况下,客户端机密显然不被视为机密。)

所以在这种情况下,client_secret 不是秘密,对吧? credentials.json的 rest 怎么样? 有人可以冒充我的应用程序并使用该信息做坏事吗?

这是首次登录的代码(有效):

function getNewToken(oAuth2Client, callback, method, args) {
    const authUrl = oAuth2Client.generateAuthUrl({
        access_type: 'offline',
        scope: SCOPES,
    });

    require('electron').shell.openExternal(authUrl);
    // mini server for authorization

    const express = require('express')()

    //express part
    express.get('/authorize', function (req, res) {
        oAuth2Client.getToken(req.query.code, (err, token) => {
            if (err) return console.error('Error retrieving access token', err);
            oAuth2Client.setCredentials(token);
            // Store the token to disk for later program executions
            fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
                if (err) return console.error(err);
                console.log('Token stored to', TOKEN_PATH);
            });
            method(oAuth2Client, callback, args);

        });
        res.sendFile(path.join(__dirname, 'authorize.html'));
    });

    express.listen(3000, () => {
        console.log(`Example app listening at http://localhost:3000`)
    })

}

如果保存了令牌,我用来访问 API 的 function :

function ApiCall(method, callback, args) {
    fs.readFile('credentials.json', (err, content) => {
        if (err) return console.log('Error loading client secret file:', err);
        // Authorize a client with credentials, then call the Gmail API.
        var credentials = JSON.parse(content);
        var {client_secret, client_id, redirect_uris} = credentials.web;
        var oAuth2Client = new google.auth.OAuth2(
            client_id, client_secret, redirect_uris[0]);

        // Check if we have previously stored a token.
        fs.readFile(TOKEN_PATH, (err, token) => {
            if (err) return getNewToken(oAuth2Client, callback, method, args);
            oAuth2Client.setCredentials(JSON.parse(token));
            method(oAuth2Client, callback, args);
        });
    });
}

以这种方式分发客户端机密是不安全的,因为它很容易被攻击者从您的应用程序中窃取。 客户端 ID 可以安全地分发,仅靠它不足以进行攻击。 您不需要项目 ID 进行授权。

您要实现的流程在 oAuth 中称为授权码授予类型。 您还需要实现PKCE 扩展。 总之,授权码 + PKCE 是在最终用户设备上运行的本机应用程序中使用 oAuth 的推荐方法。

Google 使用 OpenId Connect 将没有 PKCE 的授权代码记录为“服务器流”(有点用词不当)。 后者是 oAuth 的超集,以上所有内容仍然适用:

  1. 创建防伪 state 令牌
  2. 向 Google 发送身份验证请求
  3. 确认防伪state token
  4. 访问令牌和 ID 令牌的交换代码
  5. 从 ID 令牌中获取用户信息
  6. 验证用户

您的申请中可能不需要步骤 5-6。

您可以尝试使用google-api-nodejs-client在 JS 中滚动步骤 1-4,或者您可以试一试 oidc-client-js

只是在查看另一个项目的谷歌 oauth github 存储库,并遇到了这个:

如果您从已安装的应用程序(如 Electron)使用 OAuth2 进行身份验证,您可能不想将 client_secret 嵌入应用程序源中。 要解决此限制,您可以在 Google Developers 控制台中创建 OAuth2 凭据时选择 iOS 应用程序类型:

https://github.com/googleapis/google-auth-library-nodejs#oauth2-with-installed-apps-electron

不确定这如何阻止另一个应用程序以相同的方式使用您的客户端 ID,但这是他们的建议。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM