briancmpbll / home_assistant_custom_envoy

178 stars 76 forks source link

Long term (6 months) JWT token #13

Closed edasque closed 2 years ago

edasque commented 2 years ago

Hi,

first I want to thank you for creating this form for the newer Envoy local APIs and that nonsensical custom authentication scheme they rolled out. I've used it locally in my Home Assistant setup. While I was researching the topic, I found out that there is a way to grab a token that lasts more than 1h and it's very similar to what you have, albeit with a slightly different web flow (but very close to the form POST that you do today).

I copy pasted some code here if you want to check it out. I would write a PR but I don't know Python/HomeAssitant well.

In essence, it's a similar web flow that you can experience by going to: https://enlighten.enphaseenergy.com/entrez-auth-token?serial_num=SERIALNUMBER - If you don't want to have the user input the serial number (in addition to Enlighten Credentials) on setup, maybe this provides a way to find the serial through ZeroConf/mDNS.

briancmpbll commented 2 years ago

Thanks for the code! I don't know go at all, so it will take me quite a while to port this. I don't have a ton of time to work on this but I can make an attempt at some point.

stratus-ss commented 2 years ago

I might be able to help with this. I know both languages with some fluency (Python more than Go). I'll see if I can get some time to poke through this

edasque commented 2 years ago

To be honest this Go code is pretty self explanatory, I am happy to write it up as pseudo code. It's essentially: 1) POST the enlighten email & password to the login endpoint of the page with the log form. Hold on to the cookies 2) With the cookies in hand, GET https://enlighten.enphaseenergy.com/entrez-auth-token?serial_num=ENVOYSERIAL" - which returns a JSON document. The Token property of the JSON is a JWT token that will last 6 months (you'd renew it by going through the process again) 3) With the JWT token, you'll POST it to the endpoint of a form which is https://entrez.enphaseenergy.com/entrez_tokens 4) You grab those cookies and equipped with that, you can hit your local envoy endpoints

stratus-ss commented 2 years ago

This seems like a fun weekend project. Might be able to steal a few hours. I just started using this integration and would love to completely bypass the online requirement portion. Sadly I bought Enphase after talking to them specifically about the local API access.

I have a vested interest in seeing if we can get close to a total off-line state.

stratus-ss commented 2 years ago

When looking at @briancmpbll code, isn't he already getting the 6month jwt?

image

This seems pretty close to my own quick hack:

>>> import requests
>>> payload = { "user[email]":"enphase@someemail.com","user[password]":"Taco-Playlist"}
>>> with requests.Session() as s:
...  p = s.post('https://enlighten.enphaseenergy.com//login/login', data=payload)
...  r = s.get('https://enlighten.enphaseenergy.com/entrez-auth-token?serial_num=SOMESERIAL')

>>> r.text
'{"generation_time":1656279809,"token":"REDACTED","expires_at":1671831809}'

Which translates to an expiry Dec 23, 2022.

I haven't stepped through the original code, but presumably if its using the same url, it should also be a 6 month expiry should it not?

briancmpbll commented 2 years ago

Closing this as stale. If you want to open a PR for this change please create another issue with the PR.