0

I am trying to run a script off of my Google Drive through the Javascript Google Drive API. This works fine, but only if I sign into my account on the popup that opens. I wish to sign into the same account every time and so was wondering if there was any way to automate the login of this so as to bypass users having to enter in that login information.

pinoyyid
  • 21,499
  • 14
  • 64
  • 115
Kieran
  • 13
  • 5

2 Answers2

0

In short, you would have login at least once, everytime after the Google Identity Provider JSON Web Token expires. I am not sure how long this would be with the Goolge Drive API, but typically these tokens may be valid for anywhere from a single request to days long.

Here is the Documentation for the Google API OAuth2 https://developers.google.com/identity/protocols/OAuth2

  1. Refresh the access token, if necessary.

Access tokens have limited lifetimes. If your application needs access to a Google API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.

Note: Save refresh tokens in secure long-term storage and continue to use them as long as they remain valid. Limits apply to the number of refresh tokens that are issued per client-user combination, and per user across all clients, and these limits are different. If your application requests enough refresh tokens to go over one of the limits, older refresh tokens stop working.

Google has provided a quickstart guide for implementing a user sign via Google Apis. Google uses the OAuth2 protocol in which you must register with Google as a Client application. Once registered as a Client application, you will be issued a Client ID, which you typically provide to your application in some form of application initialization.

Here is a link to their quickstart guide, which will help you get started: https://developers.google.com/drive/v3/web/quickstart/js

Note that this is a basic example that does not demonstrate how you may approach persisting a JSON Web Token so that the user does not have to login on every request. I outline a simple approach of managing Authentication in JavaScript and Angular to get you moving in the right direction, but incomplete, direction.

For example, in Angular:

// Configures the required variables before Running an Instance of the App    
angular.module("yourModuleName").config(configureApp);

AND

// Executed when the App Instance launches, allowing you to connect to Google APIs when the App starts    
angular.module("yourModuleName").run(runApp);

Where configureApp and runApp are JS functions that handle application initialization in the AngularJS Framework. The code in the follow example would retrieve the Apps Google Client ID from their own App's REST API. This is just an example of where you could retrieve these credentials from storage, but most likely is not the most secure example:

var configureApp = function($http,$window) {
   // Setup your CLIENT ID from your own REST API (or any other mechanism you may choose)
   var httpPromise = $http.get("http://myApp.myDomain.com/config/googleClient");
   // Handle the Response from the above GET Request
   httpPromise.then(
      // Handle Success
      function(response) {
          // Store the CLIENT ID in local storage for example
          $window.localStorage.setItem("GOOGLE_API_CLIENT_ID", response.data.clientId);
          // Setup the App Wide variables for Google API
          // Client ID and API key from the Developer Console
          var CLIENT_ID = response.data.clientId;

          // Array of API discovery doc URLs for APIs used by the quickstart
          var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"];

      // Authorization scopes required by the API; multiple scopes can be
      // included, separated by spaces.
      var SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly';

   // Do more initialization configuration
};

var runApp = function() {
   // Initialize the API
   gapi.client.init({
          discoveryDocs: DISCOVERY_DOCS,
          clientId: CLIENT_ID,
          scope: SCOPES
        }).then(function () {
          // Listen for sign-in state changes.
          gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

          // Handle the initial sign-in state.
          updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
          authorizeButton.onclick = handleAuthClick;
          signoutButton.onclick = handleSignoutClick;
        });
}

Which function to use with Angular would depend on the desired app lifecycle you need to target in an Angularjs app. This approach can be applied in other JS frameworks like React and Backbone.

To highlight another perspective from the documentation, updateSigninStatus would be a great place to capture the JSON Web Token returned by Google's Authorization request at which point you could store this token in the browser's window.localStorage for re-use.

You then could reuse the token whenever the Google API requires authentication. Tokens typically have an expiration. Until the token expires, you would be able to prevent the API from displaying a login modal.

This does mean you would still have to manage the logic behind the Authorization process using this approach, monitoring any response from Google requesting a token refresh or re-authentication.

Auth0 is a great Authentication and Authorization plugin available in many languages for connecting with Google and many other OAuth2 Identity Providers. The Google Drive API uses their own Identity Provider Service to confirm the Identity of your apps users in tandem with your registered app's Client ID.

Here are links that I found when implementing Authorization for a project that required me to implement Authorization using the Google Identity Provider: https://jwt.io/ https://auth0.com/ Best practices for authentication and authorization in Angular without breaking RESTful principles? https://thinkster.io/tutorials/angularjs-jwt-auth

Community
  • 1
  • 1
Matt
  • 879
  • 9
  • 29
  • 1
    Some good stuff on this answer, but i don't think it addresses the OP's question – pinoyyid Apr 05 '17 at 08:01
  • @pinoyyid I made sure to answer his question in the first paragraph, stating that a user would have to log in at least once for every time the JSON Web Token or refresh tokens expire. The rest of the post explains why and how to create a mechanism to reduce modal pop-up logins after the initial login – Matt Apr 05 '17 at 15:08
  • Sure, but my understanding is that rather than users accessing their own Google accounts, he wishes all users to access a single common account. Thus he's looking for a way to avoid users having to know the username and password of the common account. This is achievable by having a centrally stored Refresh Token. – pinoyyid Apr 05 '17 at 18:51
  • @pinoyyid After reviewing the question again, for users to share the same credentials for the Google Drive API, then a refresh token could be shared between users. However, I believe that this is a miss-use of the Drive API. If the script needs to be accessible to a group of users, then each user should be registered as a Document Owner with the appropriate Read/Write permissions. Better yet, it sounds like this resource should be managed by the application server hosting the app so that the application can access the script behind the firewall with no authentication require. – Matt Apr 05 '17 at 22:52
  • It's not a misuse at all. In fact there is a Google video explaining how to do it. File sharing in drive is clumsy and nowhere does the OP state that his users have Google accounts – pinoyyid Apr 06 '17 at 03:31
0

You are saying that all users login to the same Google account?

In that case you have 2 options.

1/ write a server application that has a stored refresh token. Create an endpoint that allows an authenticated user to request an access token.

2/ embed a refresh token in your JavaScript, but make sure that only authenticated users can load the JS

pinoyyid
  • 21,499
  • 14
  • 64
  • 115