“Accounts failed to link” error happens when I try

2019-07-14 03:24发布

问题:

First, I'd like to mention that problems like this had been discussed before in the topics like: How to authenticate user with just a Google account on Actions on Google?

But I could not find any information at all related to ways of linking Google Assistant app with my own web server.

Problem:

GET https://oauth-redirect.googleusercontent.com/r/my-google-assistant-app#access_token=ACCESS_TOKEN&token_type=bearer&state=STATE always returns "Account field to link" error

A Way to Reproduce:

  1. I created a new project in Actions on Google Console
  2. I built an application using Dialogflow
  3. I created a Heroku Web Server as my webhook (ex: webhook.herokuapp.com)

So everything worked just fine. I've successfully connected my Google Assistant app with my webhook.

But then I decided to send requests to my another one Heroku Web Server (ex: webserver.herokuapp.com) which needs a user to be logged in. So I decided to implement account linking of my Google Assistant app with webserver.herokuapp.com

  1. I implemented Google-OAuth2 authorization at webserver.herokuapp.com. Also I want to mention that I used Client ID and Client Secret of my Google Assistant App

So, Google Authorization worked perfectly at my webserver.herokuapp.com

  1. Then I enabled account linking settings for my Google Assistant app with Implicit Flow

So, that's it!

Epilogue

I open Google Assistant, tell it "Talk to my test app", then it greets me and offers me to link accounts. I say "yes". Then I see how Google Assistant requests my login URL at webserver.herokuapp.com. Then I enter my Google email and password. As a result I logged in at my webserver! Then my webserver makes a redirection to:

https://oauth-redirect.googleusercontent.com/r/my-google-assistant-app#access_token=ACCESS_TOKEN&token_type=bearer&state=STATE

And I get the error I've described at the top of my post.

Any help would be appreciated


UPDATE with parameter information

These are my constants:
Google Assistant Project_ID = nodejs-sdk-local-test
Google Assistant Client_ID = 1067979601708-ldr3ga115es3fdo823slfnj46gjoes66.apps.googleusercontent.com
state = manually_set_state_value

The flow is I open my Google Assistant and say "Ok Google, talk to my test app", it answers my request and then I say something like "do some action which need authorization". Google Assistant app offers me to link an account and I say "Yes".

  • This is where Google Assistant app makes a call to my https://webserver.herokuapp.com/google-oauth2 endpoint. A purpose of this endpoint is to redirect me to the Google Login Page.

  • Now I'm being redirected to the Google Login Page (everything seems to be correct. client_id and state parameters are similar to the constants). This is the example of an URL where I am being redirected to: https://accounts.google.com/o/oauth2/auth?client_id=1067979601708-ldr3ga115es3fdo823slfnj46gjoes66.apps.googleusercontent.com&redirect_uri=http://webserver.herokuapp.com/complete/google-oauth2/&state=manually_set_state_value&response_type=code&scope=openid+email+profile

  • At the Google Login Page I enter my credentials and then I'm being redirected to the redirect_uri=http://webserver.herokuapp.com/complete/google-oauth2 endpoint. A purpose of this endpoint is to register or login me at webserver.herokuapp.com and then redirect me to another Google URL. An example of the Google URL: https://oauth-redirect.googleusercontent.com/r/nodejs-sdk-local-test#access_token=<token_omitted>&token_type=bearer&state=manually_set_state_value

  • So it seems that everything is correct. I logged in to my webserver.herokuapp.com, got an access token. Also project_id and state parameter in the last Google URL are similar to constants. Anyway, this Google URL returns me an error "Accounts failed to link"!

回答1:

The most common cause of this is that you're not passing back the same value for state that was sent to you when Google redirected to your site. Make sure this is the same value and, for your security, make sure you validate the other parameters that are sent to you as well.

When the user is redirected to https://webserver.herokuapp.com/google-oauth2, there should be some parameters sent as part of the query. Those parameters include a state parameter. It should look something like this:

https://myservice.example.com/auth?client_id=GOOGLE_CLIENT_ID&redirect_uri=REDIRECT_URI&state=STATE_STRING&response_type=token

Note that while the client_id and redirect_uri are values that you should expect and test for, the state value is not one that you would have set. Google generates a different one every time. This is the state that you should be using later when you redirect to

https://oauth-redirect.googleusercontent.com/r/nodejs-sdk-local-test#access_token=<token_omitted>&token_type=bearer&state=STATE_STRING