【问题标题】:Google Drive API Service Account inside domain域内的 Google Drive API 服务帐户
【发布时间】:2017-01-09 21:01:32
【问题描述】:

我必须使用 Node.js 服务器从 Drive 上的文件夹中下载/上传/删除文件。该文件夹位于公司的 G Suite 中,公司内只有少数人可以访问。

我必须使用服务帐户来执行此操作,问题是:这可能吗?我该怎么做?

我已经读过https://developers.google.com/drive/v2/web/delegationhttps://developers.google.com/identity/protocols/OAuth2ServiceAccount 但我不知道是否可以授予服务帐户访问公司域内文件夹的权限,因为服务帐户是@developer.gserviceaccount.com 而公司的域是其他的,所以给了我当我尝试将该服务帐户添加到文件夹时出错。

如果您能在这方面指导我,我将非常感激。

谢谢!

【问题讨论】:

  • 该技术是使用您作为服务帐户的权限来模拟公司域上的(任何)用户帐户。在您链接到的示例代码中,您将使用“userEmail”变量。
  • @PeterHerrmann 仅此而已?所以我只需要一个具有域范围授权的服务帐户,我就可以访问公司中所有用户的文件?
  • 是的。请更新您的问题,使其包含您想要回答的具体问题。

标签: node.js google-api google-drive-api google-oauth google-api-nodejs-client


【解决方案1】:

您可以使用具有权限范围的 oAuth 令牌:

const path = require('path');

module.exports = (app) => {
    const factory = {};
    factory.connect = (done) => {
        const fs = require('fs');
        const google = require('googleapis');
        const googleAuth = require('google-auth-library');

        const SCOPES = [
            'https://www.googleapis.com/auth/drive.metadata.readonly'
        ];
        const TOKEN_DIR = path.resolve(app.root, 'server','config');
        const TOKEN_PATH = path.resolve(TOKEN_DIR,'token.json');

        const creds = require(path.resolve(app.root, 'server', 'config', 'google_oauth.json'));
        authorize(creds, (ret) => {
            done(null, ret);
        });

        /**
         * Create an OAuth2 client with the given credentials, and then execute the
         * given callback function.
         *
         * @param {Object} credentials The authorization client credentials.
         * @param {function} callback The callback to call with the authorized client.
         */
        function authorize(credentials, callback) {
            const clientSecret = credentials.installed.client_secret;
            const clientId = credentials.installed.client_id;
            const redirectUrl = credentials.installed.redirect_uris[0];
            const auth = new googleAuth();
            const oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

            // Check if we have previously stored a token.
            fs.readFile(TOKEN_PATH, function (err, token) {
                if (err) {
                    console.error('[ERROR] Unable to read token', err)
                    getNewToken(oauth2Client, callback);
                } else {
                    oauth2Client.credentials = JSON.parse(token);
                    callback(oauth2Client);
                }
            });
        }

        /**
         * Get and store new token after prompting for user authorization, and then
         * execute the given callback with the authorized OAuth2 client.
         *
         * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
         * @param {getEventsCallback} callback The callback to call with the authorized
         *     client.
         */
        function getNewToken(oauth2Client, callback) {
            const authUrl = oauth2Client.generateAuthUrl({
                access_type: 'offline',
                scope: SCOPES
            });
            console.log('Authorize this app by visiting this url: ', authUrl);
            const readline = require('readline');
            const rl = readline.createInterface({
                input: process.stdin,
                output: process.stdout
            });
            rl.question('Enter the code from that page here: ', function (code) {
                rl.close();
                oauth2Client.getToken(code, function (err, token) {
                    if (err) {
                        console.log('Error while trying to retrieve access token', err);
                        return;
                    }
                    oauth2Client.credentials = token;
                    storeToken(token);
                    callback(oauth2Client);
                });
            });
        }

        /**
         * Store token to disk be used in later program executions.
         *
         * @param {Object} token The token to store to disk.
         */
        function storeToken(token) {
            try {
                fs.mkdirSync(TOKEN_DIR);
            } catch (err) {
                if (err.code != 'EEXIST') {
                    throw err;
                }
            }
            fs.writeFile(TOKEN_PATH, JSON.stringify(token));
            console.log('Token stored to ' + TOKEN_PATH);
        }

    };
    return factory
};

然后factory.connect(done) 将给done 一个auth 以使用googleapis

                const google = require('googleapis');
                const service = google.drive('v3');
                service.files.list({
                    auth,
                    pageSize: 10,
                    fields: 'nextPageToken, files(id, name)'
                }, step);

【讨论】:

  • 您的解决方案是客户端 ID 连接,但问题是关于服务帐户连接。
  • 我不知道标题是否已更改,问题描述为: > 我必须使用 Node.js 服务器从 Drive 上的文件夹中下载/上传/删除文件。该文件夹位于公司的 G Suite 内,公司内只有少数人可以访问。这回答了恕我直言...
  • Martin 可能会像你想象的那样做出改变 :)
猜你喜欢
  • 2019-12-12
  • 2014-09-26
  • 2021-02-10
  • 1970-01-01
  • 1970-01-01
  • 2020-04-02
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
相关资源
最近更新 更多