i8beef / HomeAutio.Mqtt.GoogleHome

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Acount linking issue

balthus opened this issue · comments

Hello,
Forgive me if these might seem basic or easy question but I've troubles since yesterday to use googlehome.
I think the issue is coming from the account linking or oath expiring, so I'm trying to make it work again but I've been trying for few hours now and still get stuck.
I want to regenerate a clean fresh tokens.json, but I don't know how/when it is done.

What I did is :

  • updated the appSettings.json with a new client id, secret, name.
  • moved the token.json to ./old
  • restart HomeAutio
  • Go in google console and update the account linking info(OAuth Client Information )
  • Then try testing

Then it always fails. The tokens.json is not regenerated.

I see that there are request coming to the server:

[13:51:29 INF] Request starting HTTP/1.0 OPTIONS http:/// - -
[13:51:29 INF] Authorization failed. These requirements were not met:
DenyAnonymousAuthorizationRequirement: Requires an authenticated user.
[13:51:29 INF] AuthenticationScheme: Cookies was challenged.
[13:51:29 INF] Request finished HTTP/1.0 OPTIONS http:/// - - - 302 0 - 2.5030ms

It used to work fine for nearly 2 years but now I'm stuck there ;(

Here is my current config.
Some settings are still unclear to me what they do :
refreshTokenGracePeriod
refreshTokenLifetime
refreshTokenReuse

I tried various combination, restart, launch the gaction script, refresh from google home android, trigger action from google console...
I can't make this token to be refreshed ;(

{
  "deviceConfigFile": "config/googleDevices.json",
  "logPII": true,
  "appPathBase":  null,
  "mqtt": {
    "brokerIp": "192.168.1.254",
    "brokerPort": 1883,
    "brokerUsername": null,
    "brokerPassword": null,
    "brokerUseTls": false
  },
  "googleHomeGraph": {
    "agentUserId": "zzz_homegraph_agent",
    "apiKey": "zzzzzz",
    "serviceAccountFile": null
  },
  "oauth": {
    "tokenStoreFile": "config/tokens.json",
    "authority": "https://home.zzzzz/",
    "requireSSL": true,
    "refreshTokenGracePeriod": 30,
    "signingCerts": null,
    "clients": [
      {
        "clientId": "zzzz",
        "clientSecret": "zzzzzz",
        "clientName": "zzzzzzzzzz",
        "allowedRedirectUris": [ "https://oauth-redirect.googleusercontent.com/r/myhome-zzzz" ],
        "refreshTokenLifetime": 365,
        "refreshTokenReuse": false
      }
    ],
    "users": [
      {
        "subjectId": "00000000-0000-0000-0000-000000000000",
        "username": "xxxx",
        "password": "zzzz"
      }
    ]
  },
  "Serilog": {
    "Enrich": [ "FromLogContext" ],
    "MinimumLevel": "Verbose",
    "WriteTo": [
      { "Name": "Console" },
      {
        "Name": "RollingFile",
        "Args": {
          "pathFormat": "logs/HomeAutio.Mqtt.GoogleHome.log",
          "retainedFileCountLimit": 31
        }
      }
    ]
  }
}
~  

Did you relink your account in the Google Home app? You have to reauthorize Google to talk to your app, which should then regenerate the token file and use it for auth beyond that point.

Of the settings you mentioned

  1. refreshTokenLifetime - Needs to be set, and should be a longer time period. I use 365 days, as this needs to span the longest time you have between triggering Google to call you. If its shorter, once the refresh token expires, Google won't be able to call to get new auth tokens with it, and will have to be relinked.

The other two are for combatting when Google makes multiple calls to you at the same time that require refresh token usage. Since the default secure model is those get EXPIRED as soon as they are used, if you have multiple calls trying to use the same token at the same time, the first one WINS and the rest fail.

  1. refreshTokenReuse - Instead of making refresh tokens "one use" by expiring them on use, this leaves them around until their natural expiration. Tokens will proliferate, but eventually get cleaned up. Less secure as a used refresh token can be used again if its intercepted by someone to get auth tokens... but the multiple calls will all complete and whichever call finished last will leave Google with a good token for subsequent calls.
  2. refreshTokenGracePeriod - The less nuclear option: Tokens still get expired on use, but they ARE reusable for a short grace period. This would allow those parallel calls to all finish the same as with token reuse, but shortly after it occurs, those used tokens will get expired. Safer than the above option from an OAuth standpoint.

In normal operation, you really shouldn't need those, they are just exposed as an option for troubleshooting, but the latter is safer (more secure) to use if you do. Also this page should explain what most of the app settings do: https://github.com/i8beef/HomeAutio.Mqtt.GoogleHome/wiki/Config:-appsettings.Production.json

ok, I spend another hour today.
I started again from scratch (reused my previous docker-compose file).
I deleted my old google project, then need to unlink it from google home app.
I recreated a new project following step by step the wiki.
Hopefully part of the existing config was still okay (URL, SSL, ha_proxy...)
Then I added/linked the project to google home, it asked for the username/pwd that we specify in the appSetting.json. I supposed I could have just unlink/relink with this step.

After that if finally worked again.
I understood a bit better what the steps are and what they mean.
The good news is that I'm now using your latest image and hope there won't be bugs but I will discover it soon ;)
Sorry to have hijacked your ticket system with this.

I still don't understand why it stopped working suddenly after 2 years...
I suspect because I saw in the previous install that the expiration was nearly about to reach...
Now I see that in tokens.json, there is:

lbatha@lba-firewall:~/projects/incubator/google_home2$ cat config/tokens.json |jq
{
  "zzzzzzzzzzzzzzzzzzzzzzzzxzcefzec": {
    "Key": "zzzzzzzzzzzzzz",
    "Type": "refresh_token",
    "SubjectId": "00000000-0000-0000-0000-000000000000",
    "SessionId": "12345",
    "ClientId": "MyClientId",
    "Description": null,
    "CreationTime": "2023-02-05T16:31:52Z",
    "Expiration": "2024-02-05T16:31:52Z",
    "ConsumedTime": null,

So maybe in one year I will get into trouble again?

No worries, that's what Im here for, feel free to ask questions.

The refresh token being set to a 365 day validity means that Google can use to get an "auth token" at any time while that token is active... and as soon as it does, it gets both an auth token to use for a short period (60 minutes or so I believe by default), and a new refresh token to use for future requests (depending on configuration of the above settings).

That should mean, as long as you make at least one request within the year that causes Google to call you, your refresh token turnover should last indefinitely. If you DON'T make said request, at the end of that year the token Google is holding gets invalidated, and you'd have to relink.

Note that could also happen if (a) Google lost their token cache for some reason (never seen it happen but possible), or (b) your token store loses the token for some reason so it can't validate the refresh token Google sends, which essentially logs Google out the next time they call you and they are supposed to invalidate their token cache at that point.

So I dont know WHY you lost connection exactly, but there are several places in the chain it could happen if you were changing things.

Many Thanks for your availability and answers.
We will so how it goes after few days/months ;)
Take care,