Alternative to calling gapi.auth.authorize every time

此生再无相见时 提交于 2020-08-24 03:31:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!