Open dotproto opened 3 years ago
Hi, no, it's not possible for third-party developers to bundle GAPI with their applications.
https://www.google.com/recaptcha/api.js
- here are the comments that this code DO NOT COPY AND PASTE.
It's not possible to add a recaptcha to the extension Manifest V3 if don't allowed to add third party code
I hope that GAPI and Extensions teams can agree on a vetted list of internal libraries that can be remotely hosted if a bundling solution does not come to fruition.
Hi @dotproto Any Update on this ? We need some solution for this. Also is Google thinking something for remote hosting code, we have to deploy our changes according to requirements and google review process is very slow. we can't deploy it to chrome web store again and again
Chrome is in the process of transitioning to extension developers to a new extension platform called Manifest Version 3 (MV3). ThisNew platform introduces a number of changes to improve the security and privacy of extension users. One of the major changes coming to the platform is that extensions will no longer be allowed to run code retrieved from remote servers. In other words, extensions won't be able to fetch and
https://apis.google.com/js/api.js
as described in the Getting Started guide.On the Chrome extension team, we have been advising developers to package third-party libraries with their extensions in order to work around this limitation. I'm not personally familiar with the JS GAPI library, so I'd like to ask whether this guidance it's appropriate for this library or whether we need to explore alternative approaches.
afaik GAPI isn't a framework that can be packaged into a local file.
On Thu, Apr 1, 2021, 5:30 AM Prasanna Dubey @.***> wrote:
Hi @dotproto https://github.com/dotproto Any Update on this ? We need some solution for this. Also is Google thinking something for remote hosting code, we have to deploy our changes according to requirements and google review process is very slow. we can't deploy it to chrome web store again and againg
Chrome is in the process of transitioning to extension developers to a new extension platform called Manifest Version 3 (MV3). ThisNew platform introduces a number of changes to improve the security and privacy of extension users. One of the major changes coming to the platform is that extensions will no longer be allowed to run code retrieved from remote servers. In other words, extensions won't be able to fetch and https://apis.google.com/js/api.js as described in the Getting Started https://github.com/google/google-api-javascript-client/blob/master/docs/start.md guide.
On the Chrome extension team, we have been advising developers to package third-party libraries with their extensions in order to work around this limitation. I'm not personally familiar with the JS GAPI library, so I'd like to ask whether this guidance it's appropriate for this library or whether we need to explore alternative approaches.
— 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/713#issuecomment-811873259, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA7LRZ4JU6OF533GZAPXNMTTGRRPPANCNFSM4WAHPP6Q .
afaik GAPI isn't a framework that can be packaged into a local file. … On Thu, Apr 1, 2021, 5:30 AM Prasanna Dubey @.***> wrote: Hi @dotproto https://github.com/dotproto Any Update on this ? We need some solution for this. Also is Google thinking something for remote hosting code, we have to deploy our changes according to requirements and google review process is very slow. we can't deploy it to chrome web store again and againg Chrome is in the process of transitioning to extension developers to a new extension platform called Manifest Version 3 (MV3). ThisNew platform introduces a number of changes to improve the security and privacy of extension users. One of the major changes coming to the platform is that extensions will no longer be allowed to run code retrieved from remote servers. In other words, extensions won't be able to fetch and https://apis.google.com/js/api.js as described in the Getting Started https://github.com/google/google-api-javascript-client/blob/master/docs/start.md guide. On the Chrome extension team, we have been advising developers to package third-party libraries with their extensions in order to work around this limitation. I'm not personally familiar with the JS GAPI library, so I'd like to ask whether this guidance it's appropriate for this library or whether we need to explore alternative approaches. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#713 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA7LRZ4JU6OF533GZAPXNMTTGRRPPANCNFSM4WAHPP6Q .
So what's the solution ?
@thdoan whitelist is SO away from web standards, I don't think Google will like this idea
I hope they come up with a solution that allows us to continue using GAPI in Chrome MV3 extensions.
On Fri, Apr 2, 2021, 2:32 AM Kostiantyn Plakhotia @.***> wrote:
@thdoan https://github.com/thdoan whitelist is SO away from web standards, I don't think Google will like this idea
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/google-api-javascript-client/issues/713#issuecomment-812452966, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA7LRZ35EKWWDERRHUJV4TTTGWFLZANCNFSM4WAHPP6Q .
@kospl, @Arthur404, @thdoan, @luciferpd13, what capabilities of the GAPI are you currently leveraging in your Manifest V2 extensions? What, if any, alternatives have you considered to using this library?
@dotproto This library doesnot support Google Location API's . Its very important.
Due to New CSP Policy. None alternatives are working
@dotproto I'm using GAPI for Google Sheets integration; there is currently no GAPI replacement that I'm aware of. If Google is willing to provide a local GAPI library that we can download and package with our extensions, I'm all for it.
Based on some earlier threads linked above, I have successfully made requests to Google APIs from MV3 extensions using the approach below. This is meaningfully less convenient that using gapi, but it does work 🤷♂️
In short, you log the user in with fetchToken()
and then use that token to make further requests (see the tasks API example at the end).
/*
* Create form to request access token from Google's OAuth 2.0 server.
*/
const oauth2SignIn = (additionalScope?: string) => {
// NOTE: this needs to be a form: https://stackoverflow.com/questions/48925165/cors-issue-with-google-oauth2-for-server-side-webapps
// Create element to open OAuth 2.0 endpoint in new window.
const form = document.createElement('form');
form.setAttribute('method', 'GET');
form.setAttribute('action', oauth2Endpoint);
const params = getParams();
if (additionalScope) {
params.scope = `${params.scope} ${additionalScope}`;
}
// Add form parameters as hidden input values.
for (const p in params) {
const input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', p);
input.setAttribute('value', params[p]);
form.appendChild(input);
}
// Add form to page and submit it to open the OAuth 2.0 endpoint.
document.body.appendChild(form);
return form.submit();
};
// Parameters to pass to OAuth 2.0 endpoint (I recommend having these in some config file)
const getParams = () => ({
client_id: config.GOOGLE_CLIENT_ID,
redirect_uri: config.REDIRECT_URI,
scope: config.GOOGLE_SCOPES.join(' '),
state: window.location.pathname,
include_granted_scopes: 'true',
response_type: 'token',
});
const fetchToken = async () => {
const params = getParams();
// localStorage is used for convenience and speed and is not required
const currentAccessToken = localStorage.getItem('oauth2');
const currentScope = localStorage.getItem('scope');
if (currentAccessToken) {
// Test the auth token with an endpoint to make sure it is still valid
const result = await fetchSelf(currentAccessToken); // use whatever works for you, this hits the /me people endpoint i think
if (result.id) {
return {
accessToken: currentAccessToken,
scope: currentScope || params.scope,
};
}
}
const fragmentString = location.hash.substring(1);
// Parse query string to see if page request is coming from OAuth 2.0 server.
const urlParams: any = {};
const regex = /([^&=]+)=([^&]*)/g;
let m = null;
while ((m = regex.exec(fragmentString))) {
urlParams[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
}
if (Object.keys(urlParams).length > 0) {
localStorage.setItem('oauth2', urlParams.access_token);
localStorage.setItem('scope', urlParams.scope);
window.location.hash = '';
if (urlParams.state) {
history.pushState('', 'Dashboard', urlParams.state);
}
} else {
oauth2SignIn();
}
return {
accessToken: urlParams.access_token,
scope: urlParams.scope,
};
};
// Example API request using the accessToken above
const taskResponse = await fetch(
`https://tasks.googleapis.com/tasks/v1/lists/${taskListId}/tasks/${taskId}`,
{
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify(body),
},
);
Every one not use Google login to sign in the user, there is also a manual login. MV3 requires some serious work here
@luciferpd13 Quite sure I am using MV3 :) - the migration process was very memorable.
In the example scenario, I am not making these requests from service workers but from the popup. I also don't believe you can create and submit form elements from service workers - that is the more critical part in that example (local storage is easily worked around or not used).
@luciferpd13 In this case there is no manual login since the user is already logged into the chrome browser - you just get a token back from chrome.identity.getAuthToken
and then pass that to your endpoints (as accessToken
in the task example). My code is shared across a chrome extension and a webapp (as was originally possible with gapi), so I implemented a platform-agnostic auth solution.
@zamiang That's what I am saying every one don't use Google Login. Also I see you are just making an api calls using token but there's more to that in GAPI. I believe @dotproto might come with the solution
My examples assume OAUTH2. But you are correct that GAPI also handles the 'simple' auth method that uses an API key (https://github.com/google/google-api-javascript-client/blob/master/docs/auth.md).
For the simple method, you would just put the API key in the url params of your GET request. For example, looking at these docs (https://developers.google.com/maps/documentation/javascript/get-api-key), you would make a http GET request to this endpoint -https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&key=YOUR_API_KEY&callback=initMap
.
Are there other auth methods not covered by OAUTH2 or API keys?
@zamiang Already tried not working in manifest v3 due to CSP
Also we can't make every api calls in terms of url there are too many methods there ,that's why we are using Google scripts
@luciferpd13 Just to clarify, so script-src 'self'
prevents the extension from loading external script files. It does NOT prevent the extension from making external HTTP requests (that would be connect-src
). The reason gapi does not work in a chrome extension, is because it is a script file hosted outside of the chrome extension, not because it makes http requests to google.
If you want to make AJAX requests from a chrome extension, you need to list those urls in host_permissions
(https://developer.chrome.com/docs/extensions/mv3/match_patterns/ & https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#host-permissions) in MV3 but I believe we are getting a bit off track and into debugging your specific issue with your MV3 manifest file as it is certainly possible to make AJAX requests from a MV3 chrome extension.
The issue is more usability (I miss having automatic typescript types personally) and do wish this package could be released in a similar way to how the typescript types are packaged. As mentioned above, it is still possible to build extensions in MV3 that use google apis, it is just a bit less fast and maintainable.
@kospl, @Arthur404, @thdoan, @luciferpd13, what capabilities of the GAPI are you currently leveraging in your Manifest V2 extensions? What, if any, alternatives have you considered to using this library?
I am using GAPI to call oauth-authenticated Google APIs from my MV2 background page in my extension. My extension makes these calls in the background so cannot use the pop-up or the foreground page as a context to execute the GAPI calls. I leverage the chrome.identity API to take care of all the OAuth flow...
Potential Workarounds for MV3?
@luciferpd13 Just to clarify, so
script-src 'self'
prevents the extension from loading external script files. It does NOT prevent the extension from making external HTTP requests (that would beconnect-src
). The reason gapi does not work in a chrome extension, is because it is a script file hosted outside of the chrome extension, not because it makes http requests to google.If you want to make AJAX requests from a chrome extension, you need to list those urls in
host_permissions
(https://developer.chrome.com/docs/extensions/mv3/match_patterns/ & https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#host-permissions) in MV3 but I believe we are getting a bit off track and into debugging your specific issue with your MV3 manifest file as it is certainly possible to make AJAX requests from a MV3 chrome extension.The issue is more usability (I miss having automatic typescript types personally) and do wish this package could be released in a similar way to how the typescript types are packaged. As mentioned above, it is still possible to build extensions in MV3 that use google apis, it is just a bit less fast and maintainable.
@zamiang I already know this things. Also as I said we can't every make api calls in terms of url. That's why I am asking @dotproto to provide some solution in MV3 extension. Also this discussion is not about making api calls from extension i don't know what are you trying to prove here 🤷🏻♂️. Everyone here wants to get some way to use GAPI and some other 3rd party scripts which are not locally available
Just want to add another voice here and check to see if there are any updates on this issue. We use maps.googleapis.com in our extension and we'd love to continue to use it in MV3 but it looks like the new CSP prohibits it. @dotproto Is there a solution in the works or a workaround that you recommend?
In the PixieBrix extension, we use GAPI for the following so far:
References:
To just be able to have a user log in with popup. I can make it work in MV2, but MV3 would be great! I'm using:
const googleProvider = new firebase.auth.GoogleAuthProvider()
firebase.auth() .signInWithPopup(googleProvider)
manifest.json :
"content_security_policy": {
"extension_pages": "script-src 'self'; script-src-elem 'self' https://apis.google.com https://www.gstatic.com https://www.googleapis.com https://securetoken.googleapis.com; object-src 'self';"
},
and I get back in my console log an error:
Refused to load the script 'https://apis.google.com/js/api.js?onload=__iframefcb41660' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
@dotproto I love everything about firebase, if you could just get the PM from firebase and PM from chrome extensions together for coffee once a week I'll buy the coffee. :)
So many possibilities could be built using firebase in extensions
@dotproto Any updates on this issue ?
Looks like it's now deprecated and being replaced.
JavaScript libraries Old New Notes apis.google.com/js/platform.js accounts.google.com/gsi/client Replace old with new. apis.google.com/js/api.js accounts.google.com/gsi/client Replace old with new.
So a question is now changed to what kind of support of Chrome MV3 new library will have.
@e-roy Did you found solution? I'm migrating from manifest2 to manifest3. And have same problem.
manifest v2 is being deprecated, will there be a solution for this in v3? In my particular use case i would like to have access to reCaptcha from the extension.
https://developer.chrome.com/docs/extensions/mv3/mv2-sunset/
I got some (disappointing) clarification from the GAPI team that chrome extensions are not and will not be a supported environment.
The documentation has been updated in #795 https://github.com/google/google-api-javascript-client/blob/master/docs/start.md#supported-environments
@dotproto Late reply to your thread, but I have a question. Is the ablity to use the file picker removed entirely from v3? I cannot seem to find a ton of discussion on this specific feature.
Thank you
@nielm so does this mean that we can no longer use gapi in Chrome Extensions? Or were you able to find some workarounds?
Seems that way @eliasab16 https://github.com/google/google-api-javascript-client/commit/8c955154dc578eb880481cfb0a8b38bbdbfba0ba
@nielm do you happen to know if this restriction for Google's own code/APIs will be lifted at any point in the future?
We would really like to use the JS Google Maps in our Chrome ext.
(Subscribing to this thread.)
MV3 produces another inexplicable result. You cannot use Google’s own APIs in a chrome extension by virtue of the way they are packaged but you can make http requests all day long. Who ever is making these decisions needs to be let go.
@dotproto In the productivity Chrome extension I'm building I want to use GAPI to auth the user, and fetch their Google Calendar events.
Isn't it a good idea to whitelist script-src
from google.com
domain? This way Chrome extension developers can consume Google APIs more easily.
For Auth, the chrome.identity API performs all the wrapping you need to handle oauth.
But then you have to write your own code to call the REST APIs directly using fetch() including handling Auth rejections...
There is an example here
https://developer.chrome.com/docs/extensions/mv3/tut_oauth/
It's not great and means that you cannot use all the predefined types that gapi would give, but it is at least a solution....
(Subscribing to this thread)
Fine it seems gapi is deprecated in manifestv3 but a lot of samples (updated recently) in official documents are still using gapi, at least write some notes above those samples. I think I saw this thread before, but after some time I go to refer to official doc and see gapi again. I tried, met obstacles, google around and get back to this page again... : (
What samples?
Fix for Chrome Extensions and Firebase MV3
import { initializeApp } from "firebase/app";
import { initializeAuth } from "firebase/auth";
const app = initializeApp(firebaseConfig);
export const auth = initializeAuth(app, { popupRedirectResolver: undefined });
Hope this helps everyone :)
What samples?
Like this: https://developers.google.com/drive/picker/guides/overview and this: https://developers.google.com/drive/api/quickstart/js use gapi
Extension examples are here:
https://github.com/GoogleChrome/chrome-extensions-samples
I don't think there are GAPI MV3 examples.
@e-roy thanks for sharing! We actually made an extension specific channel in firebase auth, so those steps are no longer needed (unless you have a hard dependency on an old version of firebase)
@lidanqing-i neither of those are extensions, so they are not impacted by manifest v3 changes.
Hi everyone, does any body found any general workaround for this issue. Our extension sometimes requires solving captcha, but with Manifest V3, it is impossible to load recaptcha script https://www.google.com/recaptcha/api.js
...
Hey @rast22
There is firebase documentation on how to handle this.
@e-roy thanks for sharing! We actually made an extension specific channel in firebase auth, so those steps are no longer needed (unless you have a hard dependency on an old version of firebase)
@lidanqing-i neither of those are extensions, so they are not impacted by manifest v3 changes.
@patrickkettner thank you very much! I wish I knew how to join the discussion in this channel.
Does the auth work for emulators in a extension?
I'm using connectAuthEmulator(auth, "http://localhost:9099");
but for some reason only when using in an extension it doesn't seem to work for me.
Devs, what features GAPI you're using an your extensions?
If you are an extension developer affected by this issue, please describe what GAPI capabilities you are using and what alternative approaches you've considered.
Issue description
Chrome is in the process of transitioning extension to a new platform we commonly refer to as Manifest Version 3 (MV3). This new platform introduces a number of changes to improve the security and privacy of extension users. One of the major changes coming to the platform is that extensions will no longer be allowed to run code retrieved from remote servers. In other words, extensions won't be able to fetch
https://apis.google.com/js/api.js
as described in the Getting Started guide.On the Chrome extension team, we have been advising developers to package third-party libraries with their extensions in order to work around this limitation. I'm not personally familiar with the JS GAPI library, so I'd like to ask whether this guidance is appropriate for this library or whether we need to explore alternative approaches.
EDIT 2021-04-02: Grammar fixes. EDIT 2021-04-05: Added an intro section EDIT 2021-05-19: Chromium issue 1164452 is also related.