alandtse / tesla

Tesla custom integration for Home Assistant. This requires a refresh token be generated by third-party apps to login.
Apache License 2.0
588 stars 100 forks source link

Auth returned `login_required` #911

Closed jesserockz closed 6 months ago

jesserockz commented 6 months ago

Version of the custom_component

v3.20.3

Configuration

Email: ***
Refresh Token: ***
Auth URL: https://auth.tesla.com
Vehicle data: yes

Proxy host: https://10.1.1.242:4430
Cert: /share/tesla/selfsigned.pem
Client ID: ***

Describe the bug

After setting up the Tesla API Proxy I cannot connect Home Assistant.

Using curl directly on the api proxy works just fine with the same certificate.

$ curl \
  --cacert selfsigned.pem \
  --header "Authorization: Bearer $ACCESS_TOKEN" \
  https://10.1.1.242:4430/api/1/vehicles

{"response":[{"id":***,"vehicle_id":***,"vin":"***","color":null,"access_type":"OWNER","display_name":"Tesla","option_codes":null,"granular_access":{"hide_private":false,"training_wheels":false},"tokens":["***","***"],"state":"asleep","in_service":false,"id_s":"***","calendar_enabled":true,"api_version":73,"backseat_token":null,"backseat_token_updated_at":null,"ble_autopair_enrolled":false}],"pagination":{"previous":null,"next":null,"current":1,"per_page":1,"count":1,"pages":1},"count":1}

Debug log

2024-03-15 12:56:09.309 DEBUG (MainThread) [custom_components.tesla_custom.config_flow] Credentials successfully connected to the Tesla API
2024-03-15 12:56:09.310 DEBUG (MainThread) [custom_components.tesla_custom] <ssl.SSLContext object at 0xffff94695d50>
2024-03-15 12:56:09.350 DEBUG (MainThread) [teslajsonpy.controller] 552 endpoints loaded

2024-03-15 12:56:09.350 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19798 days, 11:03:51
2024-03-15 12:56:09.350 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-15 12:56:09.350 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-15 12:56:10.262 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-15 12:56:10.262 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '1b6719a3-246c-4fde-9216-f2e9dbe541cc-1710460570064'}

2024-03-15 12:56:11.641 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19798 days, 11:03:49
2024-03-15 12:56:11.641 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-15 12:56:11.641 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-15 12:56:12.456 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-15 12:56:12.456 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '402dc2bc-c77d-43c5-97c6-71303a44019f-1710460572260'}

2024-03-15 12:56:15.414 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19798 days, 11:03:45
2024-03-15 12:56:15.414 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-15 12:56:15.414 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-15 12:56:16.211 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-15 12:56:16.212 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '09ce5dc1-ee17-4c05-ac34-8ce0fab55aa3-1710460576004'}

2024-03-15 12:56:21.047 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19798 days, 11:03:39
2024-03-15 12:56:21.047 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-15 12:56:21.047 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-15 12:56:21.853 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-15 12:56:21.853 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '5161264f-d63a-45ba-a784-bc71ad7e36d5-1710460581658'}

2024-03-15 12:56:24.351 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19798 days, 11:03:36
2024-03-15 12:56:24.352 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-15 12:56:24.352 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-15 12:56:25.180 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-15 12:56:25.180 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '76dd72fe-02d3-4a18-b564-ae6d9ba15c65-1710460584976'}

2024-03-15 12:56:25.180 WARNING (MainThread) [homeassistant.config_entries] Config entry '***redacted email***' for tesla_custom integration could not authenticate
llamafilm commented 6 months ago

@jesserockz can you share how you fixed this issue? The login_required error usually means the refresh token has already been used. I'm trying to figure out what causes this.

By the way, I'm surprised you were able to get the cert working with an IP address! I thought it had to be a DNS name.

jesserockz commented 6 months ago

So, ip address cert works with curl, but not in HA/Python (could be some config for that though)

I ended up changing to DNS hostname, but at the same time I did the whole auth flow again to get new tokens and it started working.

jesserockz commented 6 months ago

I started to face this issue again without changing anything.

I have restarted the proxy to get a brand new refresh_token multiple times now, and then the component also refreshes successfully as per the below logs, but then it just fails to get any data.

I can also see in .storage/core.config_entries that the new auth info refresh_token is not being updated, so future restarts/attempts will always use an expired/used refresh_token.

2024-03-27 15:39:44.843 DEBUG (MainThread) [custom_components.tesla_custom.config_flow] Credentials successfully connected to the Tesla API
2024-03-27 15:39:44.844 DEBUG (MainThread) [custom_components.tesla_custom] <ssl.SSLContext object at 0xffffb0795e50>
2024-03-27 15:39:44.899 DEBUG (MainThread) [teslajsonpy.controller] 552 endpoints loaded
2024-03-27 15:39:44.900 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19810 days, 8:20:16
2024-03-27 15:39:44.900 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-27 15:39:44.900 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-27 15:39:45.701 DEBUG (MainThread) [teslajsonpy.connection] Saved new auth info {'access_token': '<REDACTED>', 'refresh_token': '<REDACTED>', 'expires_in': 1711582784}
2024-03-27 15:39:45.702 DEBUG (MainThread) [teslajsonpy.connection] Successfully refreshed oauth
2024-03-27 15:39:45.703 DEBUG (MainThread) [teslajsonpy.connection] get: https://podman:4430/api/1/products {}
2024-03-27 15:39:47.101 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in 7:59:58
2024-03-27 15:39:47.101 DEBUG (MainThread) [teslajsonpy.connection] get: https://podman:4430/api/1/products {}
2024-03-27 15:39:50.066 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in 7:59:55
2024-03-27 15:39:50.066 DEBUG (MainThread) [teslajsonpy.connection] get: https://podman:4430/api/1/products {}
2024-03-27 15:39:54.377 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in 7:59:51
2024-03-27 15:39:54.378 DEBUG (MainThread) [teslajsonpy.connection] get: https://podman:4430/api/1/products {}
2024-03-27 15:39:59.902 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in 7:59:46
2024-03-27 15:39:59.902 DEBUG (MainThread) [teslajsonpy.connection] get: https://podman:4430/api/1/products {}
2024-03-27 15:40:04.985 DEBUG (MainThread) [custom_components.tesla_custom] <ssl.SSLContext object at 0xffffb0795e50>
2024-03-27 15:40:05.058 DEBUG (MainThread) [teslajsonpy.controller] 552 endpoints loaded
2024-03-27 15:40:05.059 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19810 days, 8:19:55
2024-03-27 15:40:05.059 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-27 15:40:05.059 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-27 15:40:05.662 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-27 15:40:05.662 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '895db807-05dc-4369-aeef-309a836b88dc-1711507205462'}
2024-03-27 15:40:07.574 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19810 days, 8:19:53
2024-03-27 15:40:07.575 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-27 15:40:07.575 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-27 15:40:08.195 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-27 15:40:08.196 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '24c16a77-3ec1-4d75-9f94-ae11f4900f09-1711507207967'}
2024-03-27 15:40:10.538 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19810 days, 8:19:50
2024-03-27 15:40:10.538 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-27 15:40:10.538 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-27 15:40:11.266 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-27 15:40:11.267 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': 'db9cf67d-d2fd-4cbe-90c0-c89c0a68073c-1711507211012'}
2024-03-27 15:40:16.187 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19810 days, 8:19:44
2024-03-27 15:40:16.187 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-27 15:40:16.187 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-27 15:40:16.844 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-27 15:40:16.844 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '03aa490c-287b-4130-ac86-7dfb8fb3682b-1711507216641'}
2024-03-27 15:40:20.060 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19810 days, 8:19:40
2024-03-27 15:40:20.061 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-27 15:40:20.061 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-27 15:40:20.656 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-27 15:40:20.656 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '98d399ee-3895-46f8-a247-ebd60807209e-1711507220457'}
2024-03-27 15:40:20.656 WARNING (MainThread) [homeassistant.config_entries] Config entry '<REDACTED>' for tesla_custom integration could not authenticate
llamafilm commented 6 months ago

That’s weird. I haven’t seen this happen after an initial success. When you opened this issue you were using v3.20.3. Have you tried updating, and did you notice if that’s when the problem started?

jesserockz commented 6 months ago

I am running 3.20.4 but it was working still after updating and stopped working on Monday I believe

llamafilm commented 6 months ago

I believe a token is supposed to be good for 8 hours. Your log shows 7:59:46 remaining and then it suddenly expires. So I suspect it was never working in the first place. I think there’s a bug here in the reauth config flow, so to change the token you need to delete the car/integration and add it back. Also, I removed the OAuth piece from the proxy add on in the latest version. So now you shouldn’t have to ever restart it. I recommend the Tesla Auth app (for macOS and iOS) to generate a refresh token.

jesserockz commented 6 months ago

I did not test the token itself, but inspecting the JWT shows it to be valid and expiring at the correct time.

Any methods to get a refresh token without macOS or iOS?

llamafilm commented 6 months ago

Someone shared a python script to create the token here: https://github.com/llamafilm/tesla-http-proxy-addon/discussions/69

I like the Tesla Auth app because it cleverly intercepts the URL to avoid the copy/paste. I hope someone ports it to Android.

jesserockz commented 6 months ago

Tried that python script, it gives me the same result:

Successful token refresh, but lists no products, then fails to refresh a second time (I think the second refresh kills it because it never saved the new refresh token in the config_entry and then future calls try to use the old used token.

2024-03-30 16:49:06.462 DEBUG (MainThread) [custom_components.tesla_custom.config_flow] Credentials successfully connected to the Tesla API
2024-03-30 16:49:06.464 DEBUG (MainThread) [custom_components.tesla_custom] <ssl.SSLContext object at 0xffffaa55c4d0>
2024-03-30 16:49:06.509 DEBUG (MainThread) [teslajsonpy.controller] 552 endpoints loaded
2024-03-30 16:49:06.509 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19813 days, 7:10:54
2024-03-30 16:49:06.509 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-30 16:49:06.509 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-30 16:49:08.170 DEBUG (MainThread) [teslajsonpy.connection] Saved new auth info {'access_token': '<REDACTED>', 'refresh_token': '<REDACTED>', 'expires_in': 1711846146}
2024-03-30 16:49:08.170 DEBUG (MainThread) [teslajsonpy.connection] Successfully refreshed oauth
2024-03-30 16:49:08.171 DEBUG (MainThread) [teslajsonpy.connection] get: https://podman:4430/api/1/products {}
2024-03-30 16:49:09.479 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in 7:59:59
2024-03-30 16:49:09.480 DEBUG (MainThread) [teslajsonpy.connection] get: https://podman:4430/api/1/products {}
2024-03-30 16:49:12.140 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in 7:59:56
2024-03-30 16:49:12.141 DEBUG (MainThread) [teslajsonpy.connection] get: https://podman:4430/api/1/products {}
2024-03-30 16:49:17.064 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in 7:59:51
2024-03-30 16:49:17.065 DEBUG (MainThread) [teslajsonpy.connection] get: https://podman:4430/api/1/products {}
2024-03-30 16:49:21.510 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in 7:59:47
2024-03-30 16:49:21.511 DEBUG (MainThread) [teslajsonpy.connection] get: https://podman:4430/api/1/products {}
2024-03-30 16:49:26.782 DEBUG (MainThread) [custom_components.tesla_custom] <ssl.SSLContext object at 0xffffaa55c4d0>
2024-03-30 16:49:26.845 DEBUG (MainThread) [teslajsonpy.controller] 552 endpoints loaded
2024-03-30 16:49:26.845 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19813 days, 7:10:34
2024-03-30 16:49:26.845 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-30 16:49:26.845 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-30 16:49:27.426 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-30 16:49:27.426 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '0ba87848-7183-49ac-b395-b48defc4b327-1711770567219'}
2024-03-30 16:49:28.796 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19813 days, 7:10:32
2024-03-30 16:49:28.796 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-30 16:49:28.797 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-30 16:49:29.361 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-30 16:49:29.361 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '3fe1d960-025a-49b6-be29-97a9903cacef-1711770569160'}
2024-03-30 16:49:32.178 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19813 days, 7:10:28
2024-03-30 16:49:32.178 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-30 16:49:32.178 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-30 16:49:32.704 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-30 16:49:32.704 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '467b385c-01df-4fdd-8d74-45370bfa78f8-1711770572504'}
2024-03-30 16:49:37.511 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19813 days, 7:10:23
2024-03-30 16:49:37.512 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-30 16:49:37.512 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-30 16:49:38.051 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-30 16:49:38.051 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': 'de262671-f6be-4579-ad8a-26f5a591e725-1711770577851'}
2024-03-30 16:49:41.846 DEBUG (MainThread) [teslajsonpy.connection] Token expiration in -19813 days, 7:10:19
2024-03-30 16:49:41.846 DEBUG (MainThread) [teslajsonpy.connection] Oauth expiration detected
2024-03-30 16:49:41.846 DEBUG (MainThread) [teslajsonpy.connection] Refreshing access token with refresh_token
2024-03-30 16:49:42.349 DEBUG (MainThread) [teslajsonpy.connection] Unable to refresh sso oauth token
2024-03-30 16:49:42.350 DEBUG (MainThread) [teslajsonpy.connection] Auth returned {'error': 'login_required', 'error_description': 'Login required', 'referenceID': '488b6a78-7a2e-43cf-9120-15492effa7be-1711770582145'}
jesserockz commented 6 months ago

The access token that was printed above in the Saved new auth info works perfectly fine when using curl

$ curl --cacert cert.pem --header "Authorization: Bearer $TESLA_AUTH_TOKEN" https://podman:4430/api/1/products

{
    "response": [
        {
            "id": XXX,
            "user_id": XXX,
            "vehicle_id": XXX,
            "vin": "XXX",
            ...
        }
    ],
    "count": 1,
}
llamafilm commented 6 months ago

I don’t know what’s going on so I’m asking lots of probing questions to see if it turns up anything useful.

Which region did you choose in the addon? Is there any chance your vehicle belongs to a different region? What model/year is your car? Did you grant all scopes in your Tesla account? Do you have any Tesla energy products, and did you select that option in the integration? If so, try redoing it with vehicle only. What do you see in the addon logs after enabling debug mode?

jesserockz commented 6 months ago

I am in New Zealand and chose NA as the region. I don't have energy products and unselect that tick box and leave it selected, same result.

I have a 22MY RWD.

I granted all the scopes that were specified yes.

I am using https://github.com/iainbullock/tesla-http-proxy-docker btw running outside the HAOS box.

Actually, looking at the container logs, I see my request from curl, but nothing when this integration is trying to list products.

Perhaps python is entirely rejecting the https connection with the self signed cert.

I can regenerate it again later today when I have time to sit at the computer and try again.

I think the py library needs some more logging exposed in regards to the self signed cert stuff because at the moment it is just silent.

llamafilm commented 6 months ago

Aha! I assumed you were using my Tesla HTTP Proxy addon. It sounds like maybe a local DNS issue. Does that curl command work from inside the Home Assistant container?

I recommend putting HA and proxy both on the same docker network. If you do that, you should be using port 443, not 4430.

I don't think a bad certificate is your issue, but just in case, I pushed small change to log more details: https://github.com/alandtse/tesla/pull/934

jesserockz commented 6 months ago

Bloody DNS, it was working after I created this issue, then just decided to stop working.

Just testing from the HA container in HAOS and it is not resolving the name that is provided by my router.

jesserockz commented 6 months ago

Ok, got it working again. Sorry for wasting your time :disappointed: I changed the proxy host from podman to podman.lan which can be resolved from within the HA container. Not sure why it worked for a little, then suddenly stopped.

I wonder if there is something over and above #934 that could help in the case of DNS issues...

llamafilm commented 6 months ago

If you have any ideas for improving the code or docs, please open a PR.