Undocumented changes to chrome.identity API, or just a bug, as usual?

1,182 views
Skip to first unread message

Vladimir Yankovich

unread,
Feb 4, 2022, 4:32:51 PM2/4/22
to Chromium Extensions
Does anyone know why since today when you call getAuthToken instead of authorizing in the account in which Chrome itself is authorized, the window for selecting an account appears?

Moreover, my experiments showed that after the first successful authorization, Chrome remembers the selected account and all subsequent calls to getAuthToken immediately try to authorize in that account. Deleting the token and revoking the rights doesn't help.

This is actually horrible behavior.

If we used to live in a world of restrictions, with getAuthToken it was possible to authorize only in the account of Chrome itself. Now it's crazy, the user selects an account and has no idea that he can't change it.

Why can't Google Chrome colleagues consult with their Google oAuth2 colleagues and give us proper authorization? At least with login_hint and prompt parameters.

Simeon Vincent

unread,
Feb 4, 2022, 6:40:42 PM2/4/22
to Vladimir Yankovich, Chromium Extensions
What build of Chrome are you using (check chrome://version)? Are you logged into a profile that has sync enabled (check chrome://settings/syncSetup)?

Regarding auth token invalidation, are you calling removeCachedAuthToken() or just trying to "forget" the token by deleting it from your own storage?

Simeon - @dotproto
Chrome Extensions DevRel


--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/740b1cb7-c76c-4f46-911a-a4cfdcba5ba5n%40chromium.org.

Vladimir Yankovich

unread,
Feb 4, 2022, 6:44:12 PM2/4/22
to Chromium Extensions, Simeon Vincent, Chromium Extensions, Vladimir Yankovich
Hello, Simeon!

Chrome  98.0.4758.82.

I experimented both with and without active synchronization. The result is the same. Other than that, it doesn't matter how many Google accounts I'm logged into at the same time.

 I call removeCachedAuthToken and use revoke on the chrome://identity-internals/.

суббота, 5 февраля 2022 г. в 02:40:42 UTC+3, Simeon Vincent:

Simeon Vincent

unread,
Feb 4, 2022, 8:09:34 PM2/4/22
to Vladimir Yankovich, Chromium Extensions
Could you file a bug report on crbug.com

Simeon - @dotproto
Chrome Extensions DevRel

Cuyler Stuwe

unread,
Feb 5, 2022, 12:20:49 PM2/5/22
to Simeon Vincent, Chromium Extensions, Vladimir Yankovich
I can confirm that this API is totally borked, and has been since at least last year. Probably (significantly) longer.

The brokenness of this is also widely acknowledged throughout StackOverflow. 

I worked a freelance contract that depended on this API, and one of the client’s requests was the ability to sign out of it and sign in with another Google account.

The function to remove cached auth tokens does nothing.

The only workaround I could come up with (which often didn’t work properly across e.g., extension uninstall/reinstall cycles) was to store the token in storage, and then use it a fetch request to this endpoint:


Vladimir Yankovich

unread,
Feb 6, 2022, 9:23:13 AM2/6/22
to Chromium Extensions, cuyler...@gmail.com, Chromium Extensions, Vladimir Yankovich, Simeon Vincent
I couldn't come up with any workaround, I started a bug — https://bugs.chromium.org/p/chromium/issues/detail?id=1294609 


суббота, 5 февраля 2022 г. в 20:20:49 UTC+3, cuyler...@gmail.com:

Vladimir Yankovich

unread,
Feb 6, 2022, 10:56:38 AM2/6/22
to Chromium Extensions, Vladimir Yankovich, cuyler...@gmail.com, Chromium Extensions, Simeon Vincent
Found one workaround:

chrome.identity.clearAllCachedAuthTokens((res) => {
console.log(res)
}).

Still, there will be a number of difficulties, and I will have to store all the google open IDs on the client, but at least I know how to make the behavior of the application obvious to the user.


воскресенье, 6 февраля 2022 г. в 17:23:13 UTC+3, Vladimir Yankovich:

Cuyler Stuwe

unread,
Feb 6, 2022, 2:12:18 PM2/6/22
to Vladimir Yankovich, Chromium Extensions, Simeon Vincent, cuyler...@gmail.com
This didn’t work for my MV2 extension at all a few months ago. Maybe it’s fixed now? Maybe not.

Vladimir Yankovich

unread,
Feb 6, 2022, 2:34:59 PM2/6/22
to Chromium Extensions, salem...@gmail.com, Chromium Extensions, Simeon Vincent, cuyler...@gmail.com, Vladimir Yankovich
You're right, actually, I was inaccurate in my description of the workaround.

To return authorization through getAuthToken to the starting state, when the user can select an account (which in itself is a bug, because the behavior was different for the last 5 years for sure), you need to execute and chrome.identity.clearAllCachedAuthToken (clears the client) and https://accounts.google.com/o/oauth2/revoke?token=putYourTokenRightHere (сlears the server).

This is terrible, as now every logout revokes scopes of my extension. But this is at least understandable for the user.  And I hope that after my report, Google will not take away the ability to choose accounts. Because that's what I've been waiting for years. Especially when they killed the authorization FireBase in MV3 and LaunchWebAuthFlow deletes cookies every time you close the browser. 

*Crying Like a Little Girl*

воскресенье, 6 февраля 2022 г. в 22:12:18 UTC+3, salem...@gmail.com:

Alex Ilin

unread,
Feb 8, 2022, 7:50:48 AM2/8/22
to Chromium Extensions, yankovic...@gmail.com, salem...@gmail.com, Chromium Extensions, Simeon Vincent, cuyler...@gmail.com, Mihai Sardarescu
We've changed the default behavior of getAuthToken() more than a year ago, in Chrome 87, to be precise. We gave the users an option to choose which Google Account they want to use with an extension.

I agree that the documentation is not complete. I filed https://crbug.com/1295237 to update the documentation of getAuthToken() funciton. 

getAuthToken() remembers user's choice of an account so that getAuthToken() returns a token for the same account the next time. Otherwise, the user would have to choose an account every time getAuthToken() is called. We thought this is a good default behavior because an extension shouldn't generally care about which account has been chosen by the user.

Sorry if that's not what you wanted from this API. Your extension can explicitly specify which account to use by providing the "account" parameter to getAuthToken(). You can obtain an account id of the primary Chrome profile from the getProfileUserInfo() function (your extension should have "identity.email" permission for this):

  chrome.identity.getProfileUserInfo({accountStatus: "ANY"}, function(userInfo) {
    chrome.identity.getAuthToken({account: {id: userInfo.id}, interactive: true}, function (token) {
      console.log(token);
    });
  });

As for how to make Chrome forget the selected account. chrome.identity.clearAllCachedAuthTokens() is the right function for this.

removeCachedAuthToken() doesn't reset the account choice because Chrome might have multiple tokens issued for the same account. We could probably optimize this API and reset the account preference as soon as the last token is removed from the client.

Vladimir Yankovich

unread,
Feb 8, 2022, 8:14:57 AM2/8/22
to Chromium Extensions, alex...@chromium.org, Vladimir Yankovich, salem...@gmail.com, Chromium Extensions, Simeon Vincent, cuyler...@gmail.com, Mihai Sardarescu
It is very strange that you say that this behavior is a year old - although it is not. That said, it's very strange that you're talking about version 87, and I see that the changes took effect when you switched from version 97 to 98. But that's beside the point.

Did you watch my video? Did you read my suggestions in the error message - https://bugs.chromium.org/p/chromium/issues/detail?id=1294609 ?

If you think about what you have done, you will realize that you have broken the authorization! How does a user now do Logout and change an account?

Unfortunately, calling chrome.identity.clearAllCachedAuthTokens() is not enough. The system just restores the token. You have to do a full revocation of the token on the server.

If you didn't remember the ID, we as developers could use the Interactive and Account parameters to manage the process normally. We would have everything for that. You wanted to make it more convenient and you broke authorization! Who made that decision? Who did you consult with? Where was the draft API published?

God, please, let's fix this.




вторник, 8 февраля 2022 г. в 15:50:48 UTC+3, alex...@chromium.org:

Alex Ilin

unread,
Feb 8, 2022, 9:09:50 AM2/8/22
to Chromium Extensions, yankovic...@gmail.com, Alex Ilin, salem...@gmail.com, Chromium Extensions, Simeon Vincent, cuyler...@gmail.com, Mihai Sardarescu
chrome://identity-internals is an interface for developers, not for the end users. I see that this page might be more informative and also display information about which account is associated with which extension and allow to reset the preference.

In order to implement a proper Logout button, your extension needs to clear the local cache as well as revoke all tokens in the server. Look at how the sample identity app does this. In your case, you'd need to call clearAllCachedAuthTokens() instead of removeCachedAuthToken().

Unfortunately, if Chrome doesn't remember the account ID, it will break all existing extensions that use getAuthToken() API since they were developed with a single account support. We wanted to make this change as less disruptive for existing extensions as possible.

I see your point that getAuthToken() doesn't properly support multiple accounts being signed-in at the same time since there is no way to display the account chooser without revoking already existing token. This is being tracked in https://crbug.com/1173583. Unfortunately, this is not supported by our server-side infrastructure yet (getAuthToken() uses an internal OAuth2 implementation that doesn't match exactly the public API). 

Would it work for you if we add a forceSelectAccount parameter to getAuthToken()? forceSelectAccount will force the account selection screen even if the server has a valid token for another account.

Alex Ilin

unread,
Feb 8, 2022, 9:28:07 AM2/8/22
to Chromium Extensions, Alex Ilin, yankovic...@gmail.com, salem...@gmail.com, Chromium Extensions, Simeon Vincent, cuyler...@gmail.com, Mihai Sardarescu
> We thought this is a good default behavior because an extension shouldn't generally care about which account has been chosen by the user.

This was poorly worded, let me clarify a little bit. An extension can still query information about an account associated with the returned token if the extension wants to display the account information to the user. This can be done by querying userinfo API.

What I meant is that any of the accounts on the list should work for an extension. It's up to the user to decide which account they want to use with an extension.

Vladimir Yankovich

unread,
Feb 8, 2022, 9:32:57 AM2/8/22
to Chromium Extensions, alex...@chromium.org, Vladimir Yankovich, salem...@gmail.com, Chromium Extensions, Simeon Vincent, cuyler...@gmail.com, Mihai Sardarescu
Alex, I think you understood me and my problem perfectly.

That said, as you correctly pointed out, by solving the Logout and forced token recall problem on the server, we automatically solve the multiple login problem.

It seems to me that there are indeed many quick fixes:
1. As you suggested, add a new parameter, forceSelectAccount.
2. Add a new value for the Interactive parameter. There is no need to invent anything here, our colleagues from Google oAuth have already invented everything. I already wrote about their Promt parameter - https://take.ms/Bl52h. It solves a lot of problems.
3. To make it possible to pass not only ID to Account parameter, but for example Select value, which would be similar to previous solutions.

But taking into account the high backward compatibility requirements, your variant is the most successful. It will not lead to failures in existing extensions. Tell me, when objectively it can appear in a stable branch?

What can't be said about the solution with automatic token remembering :) I have already had 2 users write to me asking about how they had chosen the wrong account the first time they logged in and how they could see the account selection window again. And they even thought to revoke the rights of the extension in the account settings. I sadly responded by reinstalling. Now I need to do a fix, but I'd like to do it only after I know the API is stable.


вторник, 8 февраля 2022 г. в 17:09:50 UTC+3, alex...@chromium.org:

Vladimir Yankovich

unread,
Feb 8, 2022, 9:35:40 AM2/8/22
to Chromium Extensions, alex...@chromium.org, Vladimir Yankovich, salem...@gmail.com, Chromium Extensions, Simeon Vincent, cuyler...@gmail.com, Mihai Sardarescu
I agree with you. When I first saw the account selection window after calling getAuthToken a week ago, I was happy and called the team. It's a real lifesaver after MV3 broke FireBase.

But when we realized that Logout = Revocation of a token on the server, I almost cried :)

I agree that the user should have the option of which account to associate with the extension, but not once :) And the developer should be able to control this explicitly. 

вторник, 8 февраля 2022 г. в 17:28:07 UTC+3, alex...@chromium.org:

Andy Mitchell

unread,
Jun 29, 2024, 1:17:17 PMJun 29
to Chromium Extensions, Vladimir Yankovich, alex...@chromium.org, salem...@gmail.com, Chromium Extensions, Simeon Vincent, cuyler...@gmail.com, Mihai Sardarescu
I make a Gmail extension, and I really want to use getAuthToken() (because it's the only way to use the appropriate 'Chrome App' Credential type in Google Cloud Platform). 

But our extension users frequently log into multiple Gmail accounts in one Chrome window. So having "the user choose the 1 account they want to use with an extension" is too limited. 

The ideal would be a very simple equivalent to 'login_hint': 
const token = await chrome.identity.getAuthToken({email: 'b...@gmail.com'})

If they're logged and authorised for that account, it returns it. Otherwise they're asked to authorise it.
Reply all
Reply to author
Forward
0 new messages