Search code examples
oauthoauth-2.0google-oauthactions-on-googlegoogle-home

Actions on Google and Account linking failure after tokens returned


Trying to test auth in the Web Simulator using the OAuth2 Authorization Code Flow, https://developers.google.com/actions/tools/web-simulator

See: https://developers.google.com/actions/tools/testing#testing_account_linking_with_google_home_web_simulator

And: https://developers.google.com/actions/develop/identity/oauth2-code-flow

Provided you've setup your Action to require authorization against your authorization service, when you try to access your Action the Assistant advises you that you need to Link your account. In the same response the simulator provides a URL for initiating the linking process, see:

"debugInfo": {
    "sharedDebugInfo": [
        {
            "name": "Account Linking Url",
            "debugInfo": "https://assistant.google.com/services/auth/handoffs/auth/start?provider=your-google-project-id_dev&scopes=your-scopes&return_url=https://www.google.com/"
        }
    ]
}

Calling this URL (paste into a browser) will take you through an OAuth2 flow, assuming the user actions required are successful Google will call your token endpoint with the authorization code provided during the flow.

But then I was getting:

result_code=FAILURE&result_message=Account+linking+failed

It all appeared to be working from my side but Google was returning a FAILURE.


Solution

  • In my case, my token endpoint was returning my standard token response object, which included an access_token, a refresh_token, an expires_in, a session_state and another token that wasn't needed for this purpose but was standard to my token response.

    And when I tested this same response on Googles playground it was fine: https://developers.google.com/oauthplayground/

    But not so when using the Assistant URL: https://assistant.google.com/services/auth/handoffs/auth/start?provider=your-google-project-id_dev&scopes=your-scopes&return_url=https://www.google.com/

    The reason it turns out is that the Assistant does not like superfluous properties in the response object.

    I have yet to fully establish what is and isn't allowed but so far you can have:

    {
        "token_type": "Bearer",
        "access_token: "xxx",
        "refresh_token": "yyy",
        "expires_in": "zzz"
    }
    

    With these I now get:

    result_code=SUCCESS