22

我有一个现有的支持 Google Drive 的应用程序,它使用 Google Java 客户端库和服务器流身份验证。

如果您没有登录应用程序并导航到 URL,并且您在该浏览器上登录了多个 Google 帐户(只能有一个个人 Google 帐户,任何其他帐户都必须是 Google 企业帐户)OAuth 回调提供用于选择要使用的 Google 帐户的选项。

但是,在测试切换到使用 JavaScript 客户端库时,我无法使用 gapi.auth.authorize 激活多帐户选择屏幕。是否可以使用 JS 库处理多个帐户?

更新:我尝试使用immediate参数false。只要我不在弹出窗口中更改帐户,我就可以登录。如果我确实更改了帐户,我会:

https://accounts.google.com/o/oauth2/auth?client_id=433863057149.apps.googleusercontent.com&scope=https://www.googleapis.com/auth/drive.file+https://www.googleapis。 com/auth/drive.install+https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile&immediate=false&redirect_uri=postmessage&origin=https://drivedrawio。 appspot.com&proxy=oauth2relay593063763&response_type=token&state=701344514&authuser=1

在新标签中,没有任何反应。我制作了一个视频来演示

更新 2:这个针对 JS 客户端库的需要双重选择多个帐户的错误已被接受。

4

4 回答 4

44

You are not getting the multi user selection screen because of the following parameter: authuser=0 This automatically selects the first account you are signed-in with (authuser=1 would select the second etc...).

It's currently not possible to remove that param using the client library because the client library sets it automatically to 0 (this is why it claims not to handle multi-accounts) if there is no value so one way is to override it to -1 for example, this will show the multi-account chooser. Then you could also ask to access the user's profile or email at the same time you ask access to other APIs and fetch either the email of the user or its ID. Then on subsequent auth you can specify the user_id param which wil bypass the user-selection screen.

So in practice, first authorize like this:

gapi.auth.authorize({client_id: <Your Client ID>,
                     scope: 'https://www.googleapis.com/auth/drive openid', // That requires access to Google Drive and to the UserInfo API
                     authuser: -1});

The only problem with the above is that the auto-refresh of the client library will not work because every auth will by blocked at the multi-account selection screen.

The trick is to get the ID of the user using the UserInfo API, save that ID in a session cookie and use it on subsequent auth like that:

gapi.auth.authorize({client_id: <Your Client ID>,
                     scope: 'https://www.googleapis.com/auth/drive openid',
                     user_id: <The User ID>,
                     authuser: -1});

Specifying the User's ID will make sure the multi-account chooser is bypass and will allow the auto-refresh of the token from the client lib to work again.

For reference, other URL param that impact the User flow are:

  • user_id: similar than authuser (bypasses the multi-account selection screen) but you can use email address (e.g. bob@gmail.com) or the User ID you get from our Open ID Connect endpoint/Google+ API/UserInfo API
  • approval_prompt: default is auto, can be set to force to make sure that the approval/grant screen gets shown. This makes sure that the gant screen is not bypassed on subsequent auth (after first time).
  • immediate: immediate is a bit tricky, when set to true it will bypass the grant screen (kinda like approval_prompt=auto) if the user already granted approval previously, but if the user has not granted approval previously you will get redirected with an error: error=immediate_failed. If set to false it won't add special behavior and therefore fallback on the behavior setup by the approval_prompt value.

Note: immediate=true and approval_prompt=force is an invalid combination.

I think the client library is using the immediate param so that if he gets the error=immediate_failed it will restart an auth flow without the authuser param, but that's only speculations :)

于 2012-11-14T13:11:47.740 回答
3

OAuth 授权访问页面仅在不处于即时模式时显示,如果您将immediate参数设置为 false,它是否按预期工作?

于 2012-11-13T18:15:35.050 回答
3

根据http://code.google.com/p/google-api-javascript-client/issues/detail?id=11 Javascript 客户端不支持多重登录

于 2012-11-14T17:04:20.427 回答
0

注意authuser参数。例如,将此设置为“2”,即使您已经通过身份验证,系统也会提示您登录。

于 2013-04-10T21:07:01.663 回答