google / google-api-javascript-client

Google APIs Client Library for browser JavaScript, aka gapi.
Apache License 2.0
3.19k stars 1.05k forks source link

Gapi incompatible with chrome extensions #64

Open wonderfly opened 9 years ago

wonderfly commented 9 years ago

From willscott on November 28, 2012 16:34:46

Attempting to use GAPI within a chrome extension can be done in two ways: a. Modify the extension Content Security Policy + permitted domains for all of google + googleapis.com b. Use an unprivileged (sandboxed) frame for interaction with google.

If option a is chosen, the user must agree that your extension can see and mediate all of their communications with google, which is not ideal, and a scary requirement to impose.

Option b doesn't work, (the bug / feature request) because sandboxed frames are given a unique 'null' origin, causing the messages posted from shindig to fail. Gapi should detect it is loaded in this context and post messages to the wildcard origin '*', rather than the null origin.

Ideally the google api (gapi.client.load and friends) should work from a sandboxed iframe in a chrome extension.

Instead you see either: "Uncaught Error: an attempt was made to break through the security policy of the user agent." due to an attempt to access 'window.document.cookie' or "Unable to post message to chrome-extension://. Recipient has origin null." at core:rpc:shindig.random:shindig.sha1.js:1923 (in gadgets.rpctx within the feature=rpc section of that file)

Original issue: http://code.google.com/p/google-api-javascript-client/issues/detail?id=64

wonderfly commented 9 years ago

From kgra...@gmail.com on January 29, 2013 09:23:41

I see a third option - allow your extension to make cross domain XHRs and then use raw XHR or jquery to make your requests. It would be nice if there were documentation for how batch RPC requests worked so that we could use that, too.

wonderfly commented 9 years ago

From douglas....@gmail.com on April 04, 2013 18:24:06

Related to this issue, I tried using XHR and received the Content Security Policy directive error:

Refused to load the script ' https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en_US.y7peMzNYw9Q.…sv=1/d=1/ed=1/am=QQ/rs=AItRSTPTcHBp3PDrgMIPJhUoBjh4_OoUCA/cb=gapi.loaded_0' because it violates the following Content Security Policy directive: "default-src 'self' chrome-extension-resource:". Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.

Please see the steps below to repeat.

  1. gapi_script.onload = function() { gapi.load('auth:client,drive-realtime,drive-share', onLoadGapi); }
  2. xhr = new XMLHttpRequest(); xhr.open('GET', ' https://apis.google.com/js/api.js' , true) xhr.responseType = 'blob'; xhr.onload = function(e) { gapi_script.src = window.webkitURL.createObjectURL(this.response); }

    xhr.send();

Thank you for your time.

wonderfly commented 9 years ago

From khatriri...@gmail.com on May 27, 2014 04:13:08

I am facing the same issue. Anyone found solution for this. If yes then please provide.

Thanks in advance.

jcwatson11 commented 9 years ago

I am also facing the same issue. Authorization doesn't work with the javascript client. This makes the entire authorization based set of API's pretty much worthless to javascript until this gets taken care of. Please, please, please fix!

hjuinj commented 8 years ago

May I ask which additional domains I would need to add to the Content Security Policy? My extension is using the youtube analytics gapi to return the most relevant video by keyword search. And then I use the youtube iframe api to play this video in my popup.html.

I tried adding "https://apis.google.com/" to the CSP but it did not seem to work.

bsittler commented 8 years ago

Does the technique described in http://stackoverflow.com/a/21211133/2442420 resolve the problem for you?

BenjaminWinks commented 8 years ago

@bsittler It didn't work for me, I'm still getting an error that says "Uncaught gapi.auth2.ExternallyVisibleError: Invalid cookiePolicy"

Nilesh-P commented 7 years ago

Guys, You will need to use 'The standalone auth client' described in https://developers.google.com/api-client-library/javascript/features/authentication There is an example here https://github.com/google/google-api-javascript-client/blob/master/samples/authSample.html Thanks!

saurabhgoyal795 commented 7 years ago

here gapi.client.init({ apiKey: apiKey, discoveryDocs: discoveryDocs, clientId: clientId, scope: scopes }).then(function () {

not returning anything

bsittler commented 7 years ago

Chrome extensions are not among the supported environments listed here: https://developers.google.com/api-client-library/javascript/start/start-js#supported-environments

This means it might or might not work, and even if it does work you are pretty much on your own support-wise.

The OAuth 2-specific parts of gapi.client.init are not expected to work at all from a Chrome extension.

BlackGlory commented 7 years ago

@bsittler We only need a setToken() function for gapi.auth2. More info here: https://groups.google.com/forum/#!topic/google-api-javascript-client/LS5wPf4YO48

bsittler commented 7 years ago

@BlackGlory gapi.auth.setToken({access_token: ...}) should still work fine.

bsittler commented 7 years ago

Apologies, closed by accident.

jsquyres commented 6 years ago

@bsittler Is it possible for this library to fail in a more obvious way when trying to be used in a Chrome Extension? I.e., could it detect that it's running in a Chrome Extension and return an error saying that it's not supported?

I ask only because the current failure mode is tricky to figure out (e.g., I spent a lot of time digging around before I found issues like this one): you just never get a callback -- error or otherwise. This leads a developer to think that they must have done something wrong, ...etc. If the majority of gapi.auth and/or gapi.auth2 functions could indicate that they failed because they are unsupported when running in a Chrome Extension, that would be awesome.

Thanks!

TMSCH commented 6 years ago

You should be able to capture the error doing so:

gapi.auth2.init({...}).then(onInit, function(error) {
  // Initialization error.
});

We made some updates in the last months for initialization errors to be capture. Doesn't it work for you this way?

mpvoss commented 6 years ago

So are there no plans to support Chrome Extensions, @bsittler ? It's unfortunate that we can't currently integrate with private spreadsheets that the user has legitimate access to.

bsittler commented 6 years ago

I don't think the situation has changed, no. Chrome extensions however can use their own APIs for OAuth 2 and make their own cross-origin requests

jscontreras commented 6 years ago

@bsittler is right, Chrome extensions support it natively. This worked for me in my current chrome extension which authenticates with google and also uses some APIS later using the given token.


/**
   * Start the auth flow and authorizes to Firebase.
   * @param{boolean} interactive True if the OAuth flow should request with an interactive mode.
   */
  startAuth(interactive) {
    // Request an OAuth token from the Chrome Identity API.
    chrome.identity.getAuthToken({interactive: !!interactive}, (token) => {
      if (chrome.runtime.lastError && !interactive) {
        console.log('It was not possible to get a token programmatically.');
      } else if (chrome.runtime.lastError) {
        console.error(chrome.runtime.lastError);
      } else if (token) {
        // Authrorize Firebase with the OAuth Access Token.
        let credential = provider.credential(null, token);
        firebase.auth().signInWithCredential(credential).catch((error) => {
          if (error.code === 'auth/invalid-credential') {
            chrome.identity.removeCachedAuthToken({token: token}, () => {
              startAuth(interactive);
            });
          }
        }).then((user) => {
          this.onAuthenticatedFirebase(token);
        });
      } else {
        console.error('The OAuth Token was null');
      }
    });
  }
Forkest commented 6 years ago

chrome.identity.getAuthToken requires Sign in to Chrome, this is not just OAuth. For pure OAuth there is chrome.identity.launchWebAuthFlow, but it executes in an isolated in-memory environment. This leads to a problem that it requires reauthentication each time the browser is reopened. For the same reason it doesn't suggest the profile that is already logged in, you have to enter full credentials each time. These obstacles combined make it so annoying from a UX perspective that I wouldn't say it is suitable for production at all. So please consider fixing the library auth.

cjrutherford commented 5 years ago

@bsittler is right, Chrome extensions support it natively. This worked for me in my current chrome extension which authenticates with google and also uses some APIS later using the given token.

I would love to see the documentation for your example. Having some tough issues with gapi trying to do this the "hard way"....

YesYouKenSpace commented 5 years ago

I like to ask why does GAPI not work with chrome extensions while it works for normal web pages? What is the difference between them that is causing this? Sorry if this is an amateur question, but I have been googling for this but my investigation is leading nowhere after 2 hours.

azumbrunnen commented 4 years ago

Is is seriously not possible to do create a Chrome Extension using GAPI?!

cjrutherford commented 4 years ago

Hey, I've done it, but it was a pain getting it to work. (Source isn't mine too give....)

On Sun, Dec 29, 2019, 7:53 AM Adrian Zumbrunnen notifications@github.com wrote:

Is is seriously not possible to do create a Chrome Extension using GAPI?!

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/google/google-api-javascript-client/issues/64?email_source=notifications&email_token=ACICOR4CTYTATEDR3YBB4STQ3CMULA5CNFSM4AZ4V6Y2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHY6YBY#issuecomment-569502727, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACICOR6GDNURTVRR76K6DD3Q3CMULANCNFSM4AZ4V6YQ .

MauritiusKlein commented 4 years ago

@cjrutherford Could you provide us your code? I am stuck with the same problem

cjrutherford commented 4 years ago

I'll see if I can find the code and make a general example. (It was late 2018, and like I said it's a now defunct company's code really)

Joesv commented 4 years ago

@cjrutherford did you manage to make an example?

rendomnet commented 3 years ago

same problem

harleenarora commented 3 years ago

I am facing the same issue. Anyone found solution for this. If yes then please provide.