简体   繁体   中英

Is there a way to pre-check or avoid the scopes checkbox in Google's Gmail / Google Calendar OAuth approval flow?

We currently use google-api-python-client to handle our user-facing OAuth flow. We had a few users email us asking why their accounts didn't import successfully, and when we looked, their tokens didn't have the appropriate scopes. For example, we expect to find ALL of these scopes:

https://www.googleapis.com/auth/gmail.metadata openid https://www.googleapis.com/auth/userinfo.email

But we are only receiving the last 2. When we looked at the OAuth flow, we noticed that our OAuth flow looks like this (app name and account name redacted). Notice that there is a checkbox for the requested scope, and that checkbox is by default unchecked . (From mid 2020 to about a week ago, this flow had 2 additional confirmation steps, but that last checkbox was checked by default.)

在此处输入图像描述

Compare that to the OAuth flow for popular app Fantastical (many others, including Spark, look similar):

在此处输入图像描述

After finding this StackOverflow answer which links to this post on Google's blog, it appears that some apps are grandfathered in to the second flow, but the first flow is the new default. Two questions:

  1. The checkbox being unselected by default seems to be a relatively recent change, and I can't find any documentation about it. Is it the new default behavior, or is there a parameter / something in the OAuth flow we can change to have it checked by default? When it's unchecked, users assume they don't need to check it, so they press continue and then our app has to throw an error and explain to the user that they need to check that scope checkbox. It seems a bit crazy that now the checkbox is unchecked since it's a scope I'm explicitly asking for ...it's the whole point of this flow.

  2. Is there any way to make our flow consistent with that older, much easier flow that Fantastical, Spark, and any other OAuth application created before ~2018 or so still has? Or is there an ETA for those other grandfathered apps to be transitioned to the new flow? The above Google blogpost says the new flow will be "extended to existing clients at the beginning of 2019", so we're ~2.5 years overdue on that change. As it stands, it puts "new" OAuth apps (ours was created in 2019, so hardly new...) at an incredible disadvantage because it's more steps, requires explicit consent, is more prone to user error, and makes it look like our app is in any way less scrutinized or "secure" because the flow is so different from what users have been trained to do for many other apps.

It's been an issue for months now, so also putting this post up to help any others in the same position. Some additional points in case it's helpful for anyone:

  • If I take the client_id and redirect_url from that Fantastical flow and use it in the link from our app, the flow looks the same as theirs. So it seems to be driven by the client ID, not the URL or something happening in our flow.

  • Our app has gone through Google's third party security assessment and passed, so it's likely not related to the scope we're requesting or our app's status in the approval process

  • Both our flow and Fantastical's happen in webviews, so it's unlikely that it's related to one being native vs. webview

  • This happens with several different scopes we request, so it's unlikely that it's related to the scopes we're asking for (eg Fantastical's scopes are more expansive / scrutinized even more harshly than the gmail.metadata scope in our flow)

In my case (Android app) the disabled checkboxes appeared when requesting the scopes together with the sign-in options.

I avoided it by separating the sign-in from the scope request in two steps, like this:

First, do the sign-in with the requestEmail option only. For the user, this is a dialog where they can select the account, but it already grants basic stuff (profile, email and openid):

GoogleSignInOptions options =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();

GoogleSignInClient signInClient =
        GoogleSignIn.getClient(context, options);

signInClient
        .addOnCompleteListener(task -> {
            signInLauncher.launch(signInClient.getSignInIntent());
        });

Later, when handling the sign-in result, request the additional scopes (Google Drive in my case) and include the email scope again :

GoogleSignIn.requestPermissions(
        this,
        requestCode,
        account,
        emailScope, driveScope);

It's important to request the email scope again because otherwise it will be null when coming back from the permission request. But as it was already granted at sign-in, it doesn't appear on the checkboxes.

As pointed out at the end of Google's article , 'profile', 'email' and 'openid' are allowed at sign-in.

Credit goes to Max , who pointed out this approach in a comment to this answer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM