繁体   English   中英

尝试将文件上传到Google云端硬盘时,请继续收到“登录所需”错误

[英]Keep receiving Login Required error when trying to upload a file to Google Drive

我正在编写一个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"]
    }
}

如果需要,我还编写了以下预先授权的方法:

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();
}

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

以下是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();
        }
    });
}

简而言之,它查找我关注的两个文件扩展名,如果它看到它们,那么它应该使用另一个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);
    }
}

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

在此输入图像描述

如何在此处正确登录我需要做什么? 我已尝试在标头中添加Authorization属性,但得到相同的错误。

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

这可能有助于其他人绊倒这个问题。
如果您确实使用JWT进行了授权,请确保在API调用中包含auth: <your jwtClient> ,例如:

首先,获取令牌:

// Configure JWT auth client
var privatekey = require("./<secret>.json")
var jwtClient = new google.auth.JWT(
  privatekey.client_email,
  null,
  privatekey.private_key,
  ['https://www.googleapis.com/auth/drive']
);

// Authenticate request
jwtClient.authorize(function (err, tokens) {
  if (err) {
    return;
  } else {
    console.log("Google autorization complete");
  }
});

然后,调用API (但不要忘记auth:jwtClient部分)

drive.files.create({
    auth: jwtClient,
    resource: {<fileMetadata>},
    fields: 'id'
  }, function (err, file) {
    if (err) {
      // Handle error
    } else {
      // Success is much harder to handle
    }
});

如果您正在使用swift:在viewcontroller“import GTMSessionFetcher”的开头添加下一个模块

如果没有此库,我无法使用fetcher授权程序,它是在安装pod文件时创建的

暂无
暂无

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

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