Continuously encountering a Login Required message while attempting to upload a file on Google Drive

I am currently developing a chrome extension that is designed to intercept specific downloads, like .doc and .docx files, and automatically upload them to a designated folder in Google Drive. Below is the manifest for this extension:

{
    // Manifest details.
    "manifest_version": 2,
    "name": "Extension",
    "description": "Application for SpartaHack 2016",
    "version": "1.0",
    "browser_action": {
        "default_icon": "icon.png",
        "default_popup": "popup.html"
    },
    // Content security policy for accessing gapi script.
    "content_security_policy": "script-src 'self' https://apis.google.com; object-src 'self'",
    // Necessary permissions for downloads and identity access.
    // Additional permissions required for external file access.
    "permissions": [
        "downloads",
        "identity",
        "http://*/",
        "https://*/"
    ],
    // Authorization information.
    "oauth2": {
        "client_id": "id",
        "scopes": [
            "https://www.googleapis.com/auth/drive.file",
            "https://www.googleapis.com/auth/userinfo.profile"
        ]
    },
    // Background scripts.
    "background": {
        "scripts": ["client.js", "eventPage.js"]
    }
}

In addition to the manifest, I have implemented the following method for authorization when necessary:

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

This code snippet serves the purpose of obtaining user authorization and fetching their information using the provided token. The process works smoothly without any issues.

Below is the implementation of the watchDownloads() method:

function watchDownloads() {
    chrome.downloads.onCreated.addListener(function(download) {
        if(download.url.endsWith(".doc") || download.url.endsWith(".docx")) {
            // Fetch 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();
        }
    });
}

In summary, the watchDownloads() function is responsible for identifying the specified file extensions, retrieving the respective files through direct HTTP requests, and then uploading them to Google Drive using the insertFile() method which has been constructed based on various online references.

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

However, an error occurs at this stage and prevents the successful execution of the operation as depicted here https://i.sstatic.net/Rh0dj.png.

I am facing challenges in implementing the correct login procedure. Even after adding an Authorization property in the header, the issue persists. Any guidance on resolving this would be greatly appreciated.

Answer №1

If you have implemented JWT authorization, it can be beneficial for others who come across this query. Remember to add auth: <your jwtClient> in your API request as shown below:

To begin with, obtain the token:

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

// Authorize the request
jwtClient.authorize(function (err, tokens) {
  if (err) {
    return;
  } else {
    console.log("Google authorization successful");
  }
});

Next, make the API call (remember to include the auth:jwtClient part)

drive.files.create({
    auth: jwtClient,
    resource: {<fileMetadata>},
    fields: 'id'
  }, function (err, file) {
    if (err) {
      // Handle error
    } else {
      // Dealing with success is more challenging
    }
});

Answer №2

Google's integration with various products, including Google Drive API, relies on oAuth2.0 as its authorization mechanism. Every request made must be authorized.

To learn how to authorize your application to use the Drive API, refer to the official documentation.

  1. Registration of your application is done through the Google Developers Console upon creation. Necessary information like client ID and client secret will be provided for future access.
  2. Enable the Drive API within the Google Developers Console. (Omit this step if the API isn't visible in the Console.)
  3. Your application seeks a specific scope of access from Google when user data access is required.
  4. A consent screen is presented by Google for user approval to allow your application to request certain user data.
  5. If approved, Google issues a temporary access token to your application.
  6. The application fetches user data by appending the access token to the request.
  7. Once Google validates the request and token, it returns the requested data.

For full access to user files, utilize

https://www.googleapis.com/auth/drive
, or choose a specific access level listed on the page.

Answer №3

In the case that you are utilizing Swift programming language: Ensure to include the following module at the start of your view controller "import GTMSessionFetcher"

It is necessary to incorporate this library in order to utilize fetcher authorizer, as it gets installed automatically when you add it to your pod file

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble customizing a particular view within Angular

I am struggling to customize the background of a specific view in Angular. When I tried to style it with the code below, the entire view disappeared. Here is the relevant code: HTML (index.html): <div class="col-md-8 col-md-offset-2"> <div ng ...

Don't let noise linger in the background unnoticed

Within my HTML table, there are 32 cells that each possess an onclick="music()" function. This function is currently functioning correctly, with one small exception. I desire for the functionality to be such that whenever I click on a different cell, the m ...

Unable to utilize the post method in Node.js

<form class="ui form" action"/submit" method="post"> <div class="field"> <label>Time dedicated to studying:</label> <input type="number" name="study" placeholder="Total time spent on studies:"> ...

Eliminate square brackets from URL containing an array of IDs using Request.js

My nodejs express application is sending requests with an array parameter, but it's including '[]' in the query string: For example: /foo?id=1&id=3&id=5 How can I remove the square brackets '[]' from the query string? va ...

The RxJs Observer connected to a websocket only triggers for a single subscriber

Currently, I am encapsulating a websocket within an RxJS observable in the following manner: this.wsObserver = Observable.create(observer=>{ this.websocket.onmessage = (evt) => { console.info("ws.onmessage: " + evt); ...

How do I find out the properties of individual components in Material UI?

Learning material ui has been a challenge for me as I struggle to figure out the properties available for each component. For instance, in a tutorial on YouTube, they used the AppBar component like this: <AppBar title="Enter user details" /> But ho ...

employing the d3.queue method to defer execution until receiving the AJAX response

Seeking examples of integrating AJAX, d3, and PHP to extract data from a database and create graphs. Any guidance would be appreciated. I am currently using d3 to generate a force chart based on database information retrieved through AJAX and PHP. I have ...

What is the limitation in transmitting data as a JavaScript object rather than a JSON object?

As a newcomer to expressjs, I recently developed an application using it. Interestingly, when I send data in JSON format through POSTMAN, the application successfully returns the data. However, when I try to send data as a JavaScript object in the request ...

Implement a termination condition for mapping in React

Here is a code snippet to consider: <TableHead> {documents.map((docs, i) => ( <TableRow key={i}> <TableCell> {{docs.name} </TableCell> </TableRow> ))} </TableHead> I am looking for a wa ...

Update the text label to contain an input checkbox element within

I encountered this snippet of HTML in my form: <label class="ideal-radiocheck-label" onclick=""> <input id="pagamento_8" class="_input " type="checkbox" onclick="half(this,value);" checked="" value="980" name="pagamento[]" style="position: ab ...

Autocomplete fails to recognize any modifications made to the original object

I am currently utilizing the jQuery library's autocomplete() method on a text input field, setting Object.getOwnPropertyNames(projects) as the source: $(function() { $("#project").autocomplete({source: Object.getOwnPropertyNames(projects)}); } B ...

Can a PHP script be executed through an Ajax event?

Is it feasible to execute the script of a PHP file when an AJAX event is triggered? Consider this scenario: on the AJAX error, could we send the data to the error.php file, record the error, notify the admin via email, and perform any other desired action ...

Accessing data from another domain using JavaScript with Cross-Origin Resource Sharing (

After researching various CORS and JSON request discussions, I find myself puzzled as to why the first script functions correctly while the second one does not. I am eager to enhance my understanding of CORS, Javascript, XMLHTTPRequest2, and AJAX. The fol ...

Rename multiple files in bulk

With 10000 files consisting of php, html, css, and png formats that are interconnected to operate the website's engine, I am looking for a way to perform bulk renaming in order to ensure proper functionality. Not only do I need to rename the actual fi ...

Tips for resolving asynchronous s3 resolver uploads using Node.js and GraphQL

My goal is to upload an image and then save the link to a user in the database. Below is my GraphQL resolver implementation: resolve: async (_root, args, { user, prisma }) => { .... const params = { Bucket: s3BucketName, ...

When attempting to make a GET request, Express/Mongoose is returning a null array

I am having trouble retrieving the list of books from my database. Even though I have successfully inserted the data into Mongoose Compass, when I try to fetch it, all I get is an empty array. //Model File import mongoose from "mongoose"; cons ...

Switching the website address after picking an option from the drop-down menu

I have an HTML form that includes two dropdown menus. The first dropdown is populated from a database using PHP, and the second dropdown is linked to the first one and uses AJAX to update its values based on the selection from the first dropdown. My goal ...

Creating an Angular project that functions as a library and integrating it into a JavaScript project: a step-by-step guide

Is it feasible to create an Angular library and integrate it into a JavaScript project in a similar manner as depicted in the image below? The project structure shows trading-vue.min.js being used as an Angular library. Can this be done this way or is th ...

What could be causing my component to not refresh when used as a child?

I have been experimenting with some code to track rerenders. The initial approach failed when passing <MyComponent> as a child component. it("should return the same object after parent component rerenders", async () => { jest.useF ...

``Can anyone provide guidance on extracting data from Xmlhttprequest POST request on my Nodejs express backend?"

Is there a way to properly send the values of candid and candidresults to my backend route /savevote in Express? Any help on how to achieve this would be appreciated. var candid; var candidresults; ...