timdorr / tesla-api

🚘 A Ruby gem and unofficial documentation of Tesla's JSON API for the Model S, 3, X, and Y.
https://tesla-api.timdorr.com/
MIT License
2k stars 534 forks source link

auth.tesla.cn ? #299

Closed denouche closed 3 years ago

denouche commented 3 years ago

Hello One of my users reported me that he cannot login anymore since I updated my app on the new SSO login. He also told me that on his side the login page is: https://auth.tesla.cn/oauth2/v1/authorize?client_id=teslaweb-cn&response_type=code&scope=openid%20email%20profile&redirect_uri=https%3A//www.tesla.cn/openid-connect/generic&state=Ht7mUM_AjhcOj5gNaU_xHLUqy-v9TljYQOtnLUghodY&locale=zh-CN

When I asked him to login on Tesla.com he told me that this does not works. On my side, I cannot login to auth.tesla.cn.

So there would be multiple SSO servers not sharing their users databases? Have you encountered this case?

Last thing I tested on my side, when I try to load: https://auth.tesla.cn/oauth2/v3/authorize?client_id=ownerapi&redirect_uri=https%3A%2F%2Fauth.tesla.cn%2Fvoid%2Fcallback&response_type=code&scope=openid%20email%20offline_access&state=xxx I have an "invalid-redirect-uri" error.

denouche commented 3 years ago

With an account created on tesla.cn I succeed to login using this URL: https://auth.tesla.cn/oauth2/v3/authorize?client_id=ownerapi&redirect_uri=https%3A%2F%2Fauth.tesla.com%2Fvoid%2Fcallback&response_type=code&scope=openid%20email%20offline_access&state=xxxxxx

So the SSO server seems to be on auth.tesla.cn and the redirect_uri seems to be common between all SSO servers (would be logical because the Android app is the same everywhere)

Last thing, the /authorize page seems to be different on auth.tesla.cn and auth.tesla.com , there is one more step on auth.tesla.cn (the password field is hidden when you load the page and you have to click on "Next" to see it).

denouche commented 3 years ago

The first POST to /authorize is sent with the following body:

_csrf: azertyuiopzertyuiop
_phase: identity
transaction_id: azerty
cancel: 
identity: user@email

It answer with a 200 and load the /authorize page again, with the password field this time.

Then I post the form with the password and the body contains:

_csrf: qsdfghjklqsdfghjkl
_phase: authenticate
_process: 1
transaction_id: azerty
cancel: 
identity: user@email
credential: userPassword

And this time I have the 302 response with the code in the location header.

So it seems there is an additional "identity" phase on the CN login page!

denouche commented 3 years ago

Ok so by adding the extra POST /authorize with the "identity" phase I succeed to obtain an SSO token. But... After getting it I cannot obtain an owner API token using the step 4. The answer is:

Response:
{protocol=h2, code=404, message=, url=https://owner-api.teslamotors.com/oauth/token}

Response body:
{"response":null,"error":"https://mobilesvc.teslamotors.com:443/accounts/GetUidByFederationId => {:code=>404, :message=>\"Could not get account by federation id\"}","error_description":""}

Maybe there is a CN version of owner-api.teslamotors.com ?!

denouche commented 3 years ago

login_hint query parameter on first GET /authorize seems to be the way to get the good environment, see here: https://github.com/adriankumpf/teslamate/issues/1297

timdorr commented 3 years ago

I'm guessing they distribute a different app build in China, because there are references to the tesla.cn domain in there, but I don't see any code path to actually have them set as the SSO URL or other related variables. So, there may not be that much to glean from the build in the global app stores. Given I'm not a citizen of China, I don't really have much to offer here, unfortunately.

denouche commented 3 years ago

I think the last error I have when trying to exchange my bearer against an owner API token is because my account in CN is not associated to any vehicle. So I sent an alpha version of my app to a CN user, with the login process using the login_hint query parameter, following the redirects on step 1 GET and reuse the Host value of the last redirect for step 2.and 3. I will keep you informed.

denouche commented 3 years ago

Ok so I got a feedback from the CN user I sent the alpha version of my app, and this is working for him now! So I guess the error I got Could not get account by federation id with the CN account I created for test purpose was because I have no vehicle associated with this account.

To summarize, in order to be compliant with all Tesla SSO servers, the GET at step 1 should include a login_hint query parameter with the email as value, and then 2 cases:

And the rest of the process (step 2 and step 3) should be executed on this SSO server. So in my case I just followed the redirect if any, then get the request Host, and use this new value as Tesla SSO Environment.

A big thanks to @cliffchen and @adriankumpf for finding a way to handle this!

Also note that refresh token should be done on the SSO server that originally issued the token!

timdorr commented 3 years ago

Documented in #309. Feel free to submit a PR if you want to add anything else.

denouche commented 3 years ago

Thanks! And thanks for this documentation and this repository @timdorr !!