How to use scoped APIs with (GSI) Google Identity Services - javascript

Google recently sent me an email with the following:
One or more of your web applications uses the legacy Google Sign-In JavaScript library. Please migrate your project(s) to the new Google Identity Services SDK before March 31, 2023
The project in question uses the Google Drive API alongside the now legacy authentication client.
The table on the migration page (https://developers.google.com/identity/gsi/web/guides/migration) says:
Old
New
Notes
JavaScript libraries
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.
I was currently using gapi on the front-end to perform authorization which is loaded from apis.google.com/js/api.js. According to the table I would need to replace it with the new library.
I've tried the following to authenticate and authorize in the same manner that I used to do with gapi:
window.google.accounts.id.initialize({
client_id: GOOGLE_CLIENT_ID,
callback: console.log,
scope: "https://www.googleapis.com/auth/drive.file",
discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"],
});
window.google.accounts.id.renderButton(ref.current, {
size: "medium",
type: "standard",
});
However, when I try to authenticate with the Google Sign In button, the scope field is not respected and it does not ask the user to authorize the requested scopes. It also doesn't return any form of access token in the Credential Response in the callback.
I'm not sure how else to authorize using the new library.

In the new Google Identity Services, the authentication moment and the authorization moment are separated. This means GIS provides different APIs for websites to call on these two different moments. You cannot combine them together in one API call (and UX flow) any more.
In the authentication moment, users just sign in or sign up into your website (by leveraging the information shared by Google). The only decision users need to make is whether they want to sign in (or sign-up). No authorization-related decision needs to be made at this point.
In the authentication moment, users will see consistent One Tap or button UX across all websites (since the same scopes are requested implicitly). Consistency leads to more smooth UX, which may further lead to more usage. With the consistent and optimized authentication UX (across all websites), users will have a better experience with federated sign-in.
After users sign-in, when you really want to load some data from a Google data service, you can call the GIS authorization API to trigger a UX flow to allow end users to grant the permission. That's the authorization moment.
Currently (August 2021), only authentication API has been published. If your website only cares about authentication, you can migrate to GIS now. If you also need the authorization API, you have to wait for further notice.

To add to the current answer, there is now documentation on how to authorize users with additional scope. From Using the token model.
First you need to init a TokenClient:
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: (response) => {
...
},
});
Then request for a token:
client.requestAccessToken();
If anyone is interested in where it's mentioned in the migration documentation, last paragraph of this section:
If your use case includes authorization, please read How user authorization works and Migrate to Google Identity Services to make sure your application is using the new and improved APIs.
While their articles are very detailed and good, personally I find them a bit too much for me, so it's simpler for me to just follow the first article mentioned and don't care about migrations at all.

Related

Seeking decent documentation on creating a way to link a Google account with my app

I'm trying to develop a react native application that won't require a user to sign into a bunch of different services every time. For now I'm trying to get the google side of things setup where a user can click a button which will allow me to link my application to there Google user account so that when they next visit the app the don't need to log into google for the functionality to continue to work.
I'm having a hard time finding documentation about how this link can be set up but I have found this page on Google which suggests it's possible.
https://myaccount.google.com/accountlinking?hl=en-GB&pli=1
The idea would be a bit like last.fm handles Spotify. a simple login and approve the service will mean that last.fm can listen to the Spotify account without requiring further auth every time its doing said functionality.
I can't find much in terms of tutorials or documentation on this specific thing.
Google OAuth and Scopes
It sounds like you're looking to implement Google identity federation in your app - specifically, OAuth 2.0. Google gives you quite a few options depending on the complexity of your authenticated user experience.
As for permissions, the Google API documentation calls these scopes. Here's a list of all the available scopes for every Google API. Setting scopes can take a few additional steps depending on which Google apps/information your app needs access to. By default, the Google API scopes for a new project are email, profile, and openid. Here's a video explaining how to view and modify the scopes in the Google API console(mentioned below).
1. Google Sign-in Button with scopes
The simplest method would be to follow this guide from Google which explains how to set up Google Auth on the frontend.
In short, you first set up a project within the Google API Console. Create a new project and take a look at your project scopes by clicking the Credentials tab, then the OAuth Consent Screen tab. Then back in your frontend code, include a script tag to call the Google API related to authentication functionality. Next, include a meta tag containing the client key found in the Google API Console. Then just create a sign in button with a certain class and data attribute(mentioned in the guide) and users should be able to sign in. This will return a small amount of user data in your code which you can use for validation within your app.
2. Firebase with scopes
A more complex solution would be Firebase authentication which returns even more user data, the use of a database to save and retrieve data related to the user and their session, and many other handy features that would normally be time consuming to develop. As such, Firebase is often called a backend as a service(BaaS).
To get the same level of granularity of scopes as the standard OAuth scenario outlined above, you may need to use a combination of the two as described in this article from Fireship.io.

Gmail JS API - OAuth2 Error invalid_scope

I am new to GMail JS API and I was trying to read gmail emails using Javascript according to the quickstart tutorial given explained on below link
https://developers.google.com/gmail/api/quickstart/js
I have followed all the instructions given on the page but I am getting below
error
did I miss something???
Please help me resolve this error
Thanks in advance!!!
You may refer with this thread. Make sure that you are authenticated to the API properly.
To do this, there are two ways:
use OAuth - the Server redirects the user to google's servers, where they can login, grant permission to your app, and pass a token back to
you
Service Accounts. These are a little bit more complicated:
First, you'll have to setup an app (done)
second, you'll have to setup a service account. This is how your app authenticates to google. you've done that, and the certificate
you've got contains the private key to authenticate
third, the user needs to grant your application access to act on behalf of them. This is the point you haven't done yet.
Also, as stated here, certain scopes simply aren't supported for the oauth2 for devices flow.
Additional references:
Invalid scope error when trying to access gmail api
You may refer with this thread.
As per the announcement on May 11, 2017, publicly available applications with access to certain user data must pass review. If you see an access error for your app, submit a request using our OAuth Developer Verification form.
For personal-use apps and those you are testing, join the Google group Risky Access Permissions By Unreviewed Apps, which allows you to approve data access for personal and testing accounts. See the Google API Services User Data Policy for more information.
This blog about how to fix this error might be also helpful.
OAuth invalid scope

How can public use my Instagram Application?

I'm using a JS plugin called 'Instafeed' https://github.com/stevenschobert/instafeed.js to dynamically pull in the latest image uploaded to an Instagram account.
My aim is to get this working for a government client. I tested it out on my own personal account first and found my User ID, Client ID and generated a token.
<script type="text/javascript">
// Get the most latest instagram post and insert it into the page in the DIV# instafeed
var feed = new Instafeed({
get: 'user',
userId: '249842490',
accessToken: '249842490.1677ed0.0283e662751a4e369ae856f60a4b6228',
sortBy: 'most-recent',
resolution: 'low_resolution',
limit: 1,
clientId: 'dee7958de6a64ed284b95abb1619b790'
});
feed.run();
</script>
Now to get a Client ID, I had to create an application in the Developers area. From 1st June 2016, any new applications will be sandboxed with limitations applied until it is reviewed and properly published. https://www.instagram.com/developer/limits/
It all works fine and pulls in the image as it should (e.g. https://github.com/SLQ-web/Packery-Mockup-SLQ-Homepage/blob/Ryan's-Responsive-Spec/html/widget-social.html) but I've been quizzed by PM about dependencies and vulnerabilities. I can see obvious dependencies being Instagram account, Instagram Application and the token generator).
I intend to make the Instagram application live as the 500/hour rate limit will be too small for the amount of traffic the page gets. My client seems quite concerned about security once Instagram application is made LIVE.
What I cannot answer is about security risk as in who can use the app? For what purposes? Can someone exploit the application to hack the Instagram account? Mind you I am working for extremely risk adverse client. From what I can only assume is that the application there is used by users who access the page where I have the Instafeed.js calling on the application to generate the content to show. The app is not intended for any other use.
Any time you embed information on a client, you run the risk of anyone who has access to that client somehow getting that information. This applies to websites, native mobile apps, etc.
API providers (Instagram in this case) know that this is a risk, and that's why they specifically provide you with some sort of combination of identifiers (in your case userId, accessToken, and clientId) that allow client applications to make requests, but monitor traffic related to those identifiers and provide facilities like throttling traffic, blacklisting, etc.
These types of credentials are useful because they can usually be reset (if you identify some strange traffic coming from a certain source, you can just reset your token and redeploy your application).
This type of thing falls into the realm of "API Management", and these features are pretty common. Unfortunately, the risk of someone getting those keys from your client application is always present.
If the person you're working for doesn't want people to get these credentials, you can implement some sort of user authentication client-side (one of the most common ways nowadays is OAuth, just as an example), and once clients authenticate, they can then make a call to your server, and the server would contain the Instafeed API and the userId, accessToken, etc. This just adds an additional layer between the client and Instagram, and allows you to get a little bit more control of who is making requests from your app (it still can't eliminate malicious users who would authenticate from your client-side application, but at least it keeps the access point to Instagram in a separate location, which would be your server).

No Authentication Pop up with Tumblr Like <a> link

As of now I am building out a custom Tumblr page which is basically aggregating post content into 1 page.
Problem is, we can't use the Tumblr tags for the Like, we have successfully gotten the Reblog to work, but when ever I try and use an hrefed to this pattern,
'http://www.tumblr.com/like/'+oath+'?id='+id'
and /unlike/ for unliking the post.
I can't get anything but an access denied page to come up.. Shouldn't I at least be seeing an authentication pop-up of some kind? Not sure what else to do here. Need to get this LIKE functionality working, and using the Tumblr {like button} is not an option since we aren't using a {posts block} rather pulling all our content in via JSON API.
Found an answer!
So let me break it down for you all.. I am just going to run down all the issues and caveats that were discovered while I was hacking away at the Tumblr API. In most cases you will not find any of these answers on the inter webs. If you do, they most likely will just be my answers to my own questions that I posted to the Forums.
A Tumblr Application is defined by any page template either hosted
by Tumblr or not that will be using the Tumblr API. Applications
must be registered with Tumblr at:
https://www.tumblr.com/oauth/apps
All Tumblr Applications upon creation are given a set of keys for
accessing the Tumblr API. OAuth Consumer Key aka API Key Secret Key
The Tumblr API is divided mainly into two different types of
methods. The third being “Tagged” which is for pulling tagged posts
from the Blog or the User.
“Blog Methods” which only require the submission of the Consumer
Key. “User Methods” which require a full OAuth signed request which
meets the OAuth 1.0a Protocol. The “User Likes” returns a maximum of
50 records at a time. This is not documented in the Tumblr API
docs.
Currently the Tumblr API documentation directs developers to use one of the many open source API clients. However, all these clients seem to be Server Side applications. For providers, such as Tumblr, which support only OAuth1 or OAuth2 with Explicit Grant, the authentication flow needs to be signed with a secret key that may not be exposed in the browser.
HelloJS gets round this problem by the use of an intermediary webservice defined by oauth_proxy. This service looks up the secret from a database and performs the handshake required to provision an access_token. In the case of OAuth1, the webservice also signs subsequent API requests.
HelloJS - http://adodson.com/hello.js/ is the only client-side Oauth library that was available and free. There are many services out there that charge on a per-api hit basis to serve as a proxy.
The HelloJS OAuth Proxy is available at: https://auth-server.herokuapp.com/
Login to the OAuth Proxy is done using one of the following social account credentials: Google, Windows Live, Facebook, or Yahoo.
OAuth Proxy serves as a secure “man in the middle” allowing for the “Secret Key” to be securely stored while still allowing for Client-Side OAuth authentication.
HelloJS features a special Tumblr Module - http://adodson.com/hello.js/demos/tumblr.html
HelloJS utilizes the new Javascript Promises asynchronous functions specification - https://www.promisejs.org/
Javascript Promises have some unique rules when it comes to passing objects received from an asynchronous AJAX call.
With everything is done in the callback.
What jQuery calls a promise is in fact totally different to what everyone else calls a promise.
Hope this helps for future Tumblr integrations.
John

What is OAuth authentication?

I am developing an iGoogle Gadget. I have to access the spreadsheet data of logged in user. How do I implement an OAuth for it?
You have to become an OAuth Consumer of the Google services - they are the OAuth provider in your case.
There are a lot of open source implementations of the protocol in various languages, but I would suggest to read through the RFC if you want to implement it - it's clearly written and not very long.
The official site has good reads and links too:
http://oauth.net/
Basically it's a protocol that exchanges a little bit of data between you (your application aka the consumer), the provider and your user with internal HTTP requests between you and the provider (exchanging tokens) and some redirects through the user's browser between you and the provider again.
Also, you as a consumer will have to store some tokens and data regarding these interactions. It's not very complicated and in the same time is very interesting thing to implement. I learned things about security, request signing, some http details and headers. And if you already know these things, then you will do it a lot faster than I did :)
OAuth is just an API that Google gives out to developers to let them authenticate Google accounts in other manners other than just going on google.com - for example through a programmatic way.
Authentication is the basis of it, but through OAuth you're able to retrieve lots of information from a specific Google account (calendar info, contacts etc.)
To implement this you would need to read more on their website:
https://developers.google.com/identity/protocols/OAuth2

Categories

Resources