尝试将文件上传到 Google 云端硬盘时不断收到“需要登录”错误

Ada*_*331 5 javascript drive google-chrome-extension google-drive-api google-chrome-app

我正在编写一个 chrome 扩展,它将拦截某些下载(当前为 .doc 和 .docx 文件),并获取这些文件并自动将它们上传到您的 Google 驱动程序文件夹。这是我的清单:

{
    // Default manifest crap.
    "manifest_version": 2,
    "name": "App",
    "description": "SpartaHack 2016 application",
    "version": "1.0",
    "browser_action": {
        "default_icon": "icon.png",
        "default_popup": "popup.html"
    },
    // Content security needed to access gapi script.
    "content_security_policy": "script-src 'self' https://apis.google.com; object-src 'self'",
    // Need to view downloads, and identity for obvious reasons.
    // The other two permissions allow the script to access files that are outside our domain. 
    "permissions": [
        "downloads",
        "identity",
        "http://*/",
        "https://*/"
    ],
    // Gives us the auth information.
    "oauth2": {
        "client_id": "id",
        "scopes": [
            "https://www.googleapis.com/auth/drive.file",
            "https://www.googleapis.com/auth/userinfo.profile"
        ]
    },
    // Scripts that are always running.
    // Client.js has the gapi script, eventPage is our code.
    "background": {
        "scripts": ["client.js", "eventPage.js"]
    }
}
Run Code Online (Sandbox Code Playgroud)

如果需要的话,我还编写了以下执行授权的方法:

chrome.identity.getAuthToken({
    "interactive": true
}, sendAuthToken);

function sendAuthToken(token) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=' + token, true);
    xhr.onload = function() {
        console.log(xhr.response);
    }

    //TODO: 
    xhr.send();
    console.log(token);
    watchDownloads();
}
Run Code Online (Sandbox Code Playgroud)

这个片段是我从某个地方的示例中找到的。似乎仅执行授权还不够,我还必须使用此令牌发送对用户信息的请求。这部分不会给我带来任何麻烦 - 令牌记录正常,并且记录的响应按预期显示了我的所有信息。

watchDownloads() 如下所示:

function watchDownloads() {
    chrome.downloads.onCreated.addListener(function(download) {
        if(download.url.endsWith(".doc") || download.url.endsWith(".docx")) {
            // Get blob from URL
            var xhr = new XMLHttpRequest();
            xhr.open("GET", download.url, true);
            xhr.responseType = "blob";

            xhr.onload = function(error) {
                if(this.status == 200) {
                    insertFile(this.response, function(resp) {
                        console.log(resp);
                    });
                }
            };

            xhr.send();
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

简而言之,它会查找我关心的两个文件扩展名,如果它看到它们,则应该使用另一个 HTTP 请求直接获取该文件到文件的 url,然后使用此方法将其上传到驱动器中,该方法具有大部分是根据在线样本拼凑而成的:

function insertFile(fileData, callback) {
    const boundary = "-------314159265358979323846";
    const delimiter = "\r\n--" + boundary + "\r\n";
    const close_delimiter = "\r\n--" + boundary + "--";

    //TODO: Remove
    console.log(fileData);

    var reader = new FileReader();
    reader.readAsBinaryString(fileData);
    reader.onload = function(error) {
        var contentType = fileData.type || "application/octet-stream";
        var metadata = {
            // "title": fileData.filename,
            "title": "Potato",
            "mimeType": contentType
        };

        var base64Data = btoa(reader.result);
        var multipartRequestBody =
            delimiter +
            "Content-Type: application/json\r\n\r\n" +
            JSON.stringify(metadata) +
            delimiter +
            "Content-Type: " + contentType + "\r\n" +
            "Content-Transfer-Encoding: base64\r\n\r\n" +
            base64Data +
            close_delimiter;

        //TODO: Remove
        console.log(multipartRequestBody);

        var request = gapi.client.request({
            "path": "/upload/drive/v3/files",
            "method": "POST",
            "params": {
                "key": "key",
                "uploadType": "multipart"
            },
            "headers": {
                "Content-Type": 'multipart/mixed; boundary="' + boundary + '"'
            },
            "body": multipartRequestBody
        });

        //TODO: Remove
        console.log(request);

        if(!callback) {
            callback = function(file) {
                console.log(file)
            };
        }

        request.execute(callback);
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是它失败的地方。我似乎无法让它工作,因为每次都会出现以下错误:

在此输入图像描述

我需要做什么才能在这里正确登录?我尝试Authorization在标头中添加属性,但出现相同的错误。

adj*_*ods 1

Google Drive API(以及其他 Google 产品)使用 oAuth2.0 作为其授权协议。所有提出的请求均须获得授权。

授权您的应用程序使用 Drive API 的详细步骤可以在文档中找到。

  1. 创建应用程序时,您可以使用 Google Developers Console 注册它。然后,Google 会提供您稍后需要的信息,例如客户端 ID 和客户端密钥。
  2. 在 Google Developers Console 中激活 Drive API。(如果开发者控制台中未列出该 API,则跳过此步骤。)
  3. 当您的应用程序需要访问用户数据时,它会向 Google 请求特定的访问范围。
  4. Google 向用户显示同意屏幕,要求他们授权您的应用程序请求他们的一些数据。
  5. 如果用户批准,Google 就会为您的应用程序提供一个短期访问令牌。
  6. 您的应用程序请求用户数据,并将访问令牌附加到请求中。
  7. 如果 Google 确定您的请求和令牌有效,则会返回请求的数据。

https://www.googleapis.com/auth/drive如果您想要完全访问用户的文件或页面上列出的特定文件,则可以使用。