问题
I have a single-page web application that uses Google Apps Script Execution API to call functions that return the data I need. I based my project on the quick start sample code provided by Google.
This requires the use of OAuth and I am accomplishing that via functions that make use of the client JavaScript library provided by Google.
The first time a user is asked to authenticate the following function is used with immediate: false
:
gapi.auth.authorize({client_id: CLIENT_ID, scope: SCOPES, immediate: false}, handler);
Subsequent API requests must also provide an authentication token, so I am calling the same function, but with immediate: true
:
gapi.auth.authorize({'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': true}, handler);
Each time, gapi.auth.authorize
is called, a new IFRAME
is added to the page, seemingly to store the results of the authentication operation/token, etc.
So, yes, everything works but I am thinking that there has to be a better way of doing this.
Is there another way to make subsequent API calls, after initial authentication, that doesn't require using gapi.auth.authorize
and adding yet another IFRAME
to the page?
According to Google:
Notes
After the initial user authorization, calls to gapi.auth.authorize that use immediate:true mode will obtain an auth token without user interaction.
回答1:
In short, you can't avoid the iframe (or popup which is the older way) unless you use "offline" mode. Here is the deal:
There are two distinct ways to request a permission, "offline" or "not offline".
In Offline, oauth2 gives you a permanent permission by giving you the "refresh token" (ok it's not really forever if the user revokes the permission from the google account security page, or for some scopes if the user changes their password).
This special token lets you create new access tokens whenever you want by simply doing a "GET" call to the API, without any user intervention. In your case, this is the mode you need, no way around it, this is why it exists, and you have to take special care to store it securely and so on.
In Not offline mode, you only get a temporary permission ("access token" expires in 1 hour), you do not get the "refresh token". But how does that work? somewhere there must be some refresh token or something private stored.
Authentication using the Google APIs Client Library for JavaScript takes advantage of browser security features to do this. In particular, browsers secure storage and cookies per subdomain, and once you are logged-in to the browser, google.com will store or use cookies to secure parameters that it sends to google to validate you.
So, how to read those values? Opening the google.com url is the only way to have javascript read the values. Google allows special parameters so it can communicate back the access token. How to open a page? by "iframe" or "popup" are the only ways that browsers currently support.
This allows the google page to act like a secure proxy to ask Google for stuff. A page that iframes or opens the google page (as a popup) cannot fake its own URL so this "proxy" knows what page is asking for data. The proxy can then validate with google servers for what scopes this caller has, and return a new access token. A hacker cannot fake this from a server because it does not have the cookie needed (stored in each user's browser under a google subdomain, which is the only place where "online" mode works.)
"popup" was the older way before browsers had secured iframes, but it will cause at minimum a "flash" when the popup opens and immediately closes (search for "jarring" in the link above)
Thus, later Google provided "iframe" mode which gives a much smoother experience. Using the iframe is the "immediate" mode that the link above mentions.
TLDR: gotta use "offline" or hack the user's browser.
来源:https://stackoverflow.com/questions/34342113/alternative-to-calling-gapi-auth-authorize-every-time