Closed rawmean closed 3 years ago
I presume this has to do with the MFA options coming down the pipe.
We'll definitely need to update the docs. Presumably the older auth method will continue to work (it's also OAuth 2.0, just with a password grant).
Looks like they just flipped the switch. I turned it on, so I'm going to poke around for a bit and see what's up.
Yes, but the old authentication endpoints that use email/password still work. Strange
Yup, they don't appear to respect the MFA requirement yet:
I, [2020-10-06T15:55:05.999917 #97301] INFO -- request: POST https://owner-api.teslamotors.com/oauth/token
I, [2020-10-06T15:55:05.999982 #97301] INFO -- request: User-Agent: "github.com/timdorr/tesla-api v:3.0.6"
I, [2020-10-06T15:55:06.618454 #97301] INFO -- response: Status 200
Ah, I see why. MFA is being implemented on their separate SSO server. The oAuth client ID for that server? "ownerapi"
So, the Owner API is basically a client of the SSO OAuth.
I would expect that direct auth to the Owner API will go away eventually, once enough app users have upgraded to the latest app version. I don't know their internal deprecation policy, but for the streaming API transition, that took at least a year to move to WebSockets. I don't know if they'll be so laid back for something like auth, but I don't think we're going to be shut out in the next few days or anything.
The very interesting thing is this may finally open the door for official third-party apps. If we can specify our own callback URLs (and those aren't yet locked down), you could auth to a third party site without giving away your password. Fingers crossed!
Hey, I have the solution and was able to successfully integrate it into my application. If you make a request on "oauth/token" you get an error message if the MFA is activated. If you add mfaCode to the request with the MFA code you will get the tokens.
I hope I could help you
@keymakerfd - to confirm, you are getting an error with a request to https://owner-api.teslamotors.com/oauth/token
using password auth? I'm not seeing that, anyone else?
yes, i do a request to: https://owner-api.teslamotors.com/oauth/token
Right, that makes sense but if you were to do a request to https://owner-api.teslamotors.com/oauth/token
omitting the mfaCode, it returns an error?
I am not seeing that, the request always seems to succeeds even with MFA enabled. Unless they are rolling something out now...
@bperlman I wanted to deal with the topic today and activated MFA. Always got an error until I tried the "solution" mfaCode. After that I got my new tokens immediately. It may well be that they are rolling out something. (Or maybe a rollback if you don't see a error without mfaCode ?)
@keymakerfd - to confirm, you are getting an error with a request to
https://owner-api.teslamotors.com/oauth/token
using password auth? I'm not seeing that, anyone else?
Same. I enabled MFA yesterday. I can use the https://owner-api.teslamotors.com/oauth/token endpoint using grant_type
of password
or refresh_token
(with other valid form values) like normal without adding mfaCode
. Nothing has changed for me either.
@bperlman I wanted to deal with the topic today and activated MFA. Always got an error until I tried the "solution" mfaCode. After that I got my new tokens immediately. It may well be that they are rolling out something. (Or maybe a rollback if you don't see a error without mfaCode ?)
Could be something changing on their end I suppose - I've not come across any errors with password
grant_type
or refresh_token
requests to the https://owner-api.teslamotors.com/oauth/token
endpoint.
I guess another question would be, do you get an error if you send along a mfaCode
that is incorrect?
ok, now it gets crazy. Now I only get the tokens directly without the MFA code. My steps before: 1) Tokens worked 2) MFA activated 3) Tokens were still working 4) My Tesla password changed 5) Tokens became invalid 6) changed the new password in my database 7) Error received (found the message): "{"response": "https://myt-websvc-vip1.tesla.com:443/teslamobileservices/users/authenticate_=>_authorization_required"}" (HTTP/1.1 401 Unauthorized) 8) tested, made the mistake again and again until I came across mfaCode. 9) passed mfaCode with 10) Receive Tokens
Now: Now I always get my tokens without transmitting an mfaCode. No matter if it is correct or not. I tried it again on another server of mine and it is the same there. In the meantime I changed the Tesla password again, with the same effect.
My fear: 1) Tesla is trying something 2) Or the authentication of Tesla did not work in the time frame I tested and it was a "damn" coincidence?
I'm cursing something right now
I'm working on implementing the "real" OAuth flow with the web login, so we don't ever have custody of the user's email or password.
So far I've gotten the initial login all working properly. The initial URL is https://auth.tesla.com/oauth2/v3/authorize and the keys are a little different. The secret stays the same as before, but the key changes to ownerapi
as stated above. You also need to add the PKCE stuff which is a code verifier and challenge, the verifier is generated using the old client ID, and then the challenge is an SHA256 hash of the verifier. Then token URL is https://auth.tesla.com/oauth2/v3/token and all is good, you get a token with a refresh token and an expiration.
Where I'm stuck though is with the refresh token later. Normally you'd call the token URL again with the refresh_token grant along with the original refresh token, and you'd get an updated token and expiration date. The problem is, when making this call to the token URL the request just times out. No error message or other response, just nothing.
Has anyone been messing with this and figure it out yet? Is the refresh call somehow different than normal?
@Vortec4800 are you posting to https://auth.tesla.com/oauth2/v3/authorize like we've always done in the past and it returns the code to further post to the token url? I know you listed what changed but can you share all of the required fields? I'm not able to get as far as you've gotten.
If you're familiar with OAuthSwift (or can translate to your tool of choice) this is what works for me:
let oauthSwift = OAuth2Swift(
consumerKey: "ownerapi",
consumerSecret: kTeslaSecret,
authorizeUrl: "https://auth.tesla.com/oauth2/v3/authorize",
accessTokenUrl: "https://auth.tesla.com/oauth2/v3/token",
responseType: "code"
)
private func verifier(forKey key: String) -> String {
let verifier = key.data(using: .utf8)!.base64EncodedString()
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "=", with: "")
.trimmingCharacters(in: .whitespaces)
return verifier
}
private func challenge(forVerifier verifier: String) -> String {
let hash = verifier.sha256
let challenge = hash.base64EncodedString()
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "=", with: "")
.trimmingCharacters(in: .whitespaces)
return challenge
}
let codeVerifier = self.verifier(forKey: kTeslaClientID)
let codeChallenge = self.challenge(forVerifier: codeVerifier)
let internalController = AuthWebViewController()
internalController.callbackURL = "https://auth.tesla.com/void/callback"
internalController.callingViewController = self
oauthSwift.authorizeURLHandler = internalController
let state = generateState(withLength: 20)
oauthSwift.authorize(withCallbackURL: self.callbackURL, scope: "openid email offline_access", state: state, codeChallenge: codeChallenge, codeChallengeMethod: "S256", codeVerifier: codeVerifier) { result in
switch result {
case .success(let (credential, _, _)):
print(success)
case .failure(let error):
print(error)
}
}
The AuthWebViewController
is just a web view that monitors URL requests and when it sees the callback URL, it stops and passes it back to OAuthSwift.
OAuthSwift does have a token refresh call that uses the normal flow, but that's what doesn't work on the Tesla API. I still haven't been able to figure out why the API won't return a response, maybe you'll have better luck.
@Vortec4800 what is the value of kTeslaSecret
?
That's just the normal Tesla client ID and secret. They're available from a few places online, it's in this repo as well.
Would be cool if someone could translate your code into nodejs, I couldn't find a library the supports all that
@Vortec4800 thanks for the details, can you please share the implication of AuthWebViewController, and the value of self.callbackURL?
Would be cool if someone could translate your code into nodejs, I couldn't find a library the supports all that
I'm familiar with node but I haven't tried to implement client-style OAuth from there, usually auth involves server keys or direct token communication that happened on a client somewhere. I do know it's pretty standard OAuth2 with PKCE, so if a library supports that it should work in theory.
@Vortec4800 thanks for the details, can you please share the implication of AuthWebViewController, and the value of self.callbackURL?
The callback URL is the same as the one a couple lines above, the void/callback URL.
The view controller came from OAuthSwift, I made some modifications to fit my needs but this should get you up and running. https://github.com/OAuthSwift/OAuthSwift/blob/master/Demo/Common/WebViewController.swift
anyone here was able to use token refresh call without timeout or error?
The token refresh times out if scope
parameter is not included. It seems to be hardcoded to openid email offline_access
When I call for a token using the old api, i keep getting challenged with: response: {"response": "https://myt-websvc-vip1.tesla.com:443/teslamobileservices/users/authenticate_=>_authorization_required"}
Does this mean they stopped the old interface?
https://tesla-api.timdorr.com/api-basics/authentication
Can these steps still work"?? OST /oauth/token?grant_type=password The initial authentication process is via an OAuth 2.0 Password Grant with the same credentials used for tesla.com and the mobile apps. The current client ID and secret are available here.
Yes, but the old authentication endpoints that use email/password still work. Strange
Mine does not work anymore I keep getting challenged with obscure URL l
For anyone struggling to get this working, in the interest of helping as many convert smoothly to MFA support, I cobbled this project together based on @Vortec4800 's enormously helpful comments above. If you'd just like a working example to inspect - this should do. Code is in no way cleaned up or production ready - but it does illustrate a working token flow with initial grant and subsequent refreshes (thanks @Husqvik !).
https://github.com/Kemmey/TeslaMFA
And HUGE THANK YOU to @timdorr for all your hard work on this - without this repo, my apps would not exist.
@Kemmey thanks for that. Have you experienced this giving the error stateNotEqual[j1DR8Y9OZ1cIE5PkFziz<>e8dyr5SfGQjuB070g1Bb]
?
It actually seems random, but some login attempts fail with none matching state
and some work.
@ddaddy I have not. But I'm also only in the early testing stages of mfa implementation. I did stumble on some request state matching in the oauthswift code while debugging - basically, if states don't match, you'll have crossing requests. So multiple auth requests would be fired off, with responses not being properly matched to their originators. Oauthswift should take care of that, though?
For anyone struggling to get this working, in the interest of helping as many convert smoothly to MFA support, I cobbled this project together based on @Vortec4800 's enormously helpful comments above. If you'd just like a working example to inspect - this should do. Code is in no way cleaned up or production ready - but it does illustrate a working token flow with initial grant and subsequent refreshes (thanks @Husqvik !).
https://github.com/Kemmey/TeslaMFA
And HUGE THANK YOU to @timdorr for all your hard work on this - without this repo, my apps would not exist.
Nice job, I guess I shouldn't have been lazy and done something similar as this looks very similar to what I had put together :).
Did you run into the refresh token issue I described above? Have you gotten token refreshing working? That was the last piece of the puzzle for me.
Would it be hard for some one to create a python example? We use a lot of automation on python and just looking at how to use MFA without applications as well.
On Tue, Nov 3, 2020 at 7:21 AM Cory Imdieke notifications@github.com wrote:
For anyone struggling to get this working, in the interest of helping as many convert smoothly to MFA support, I cobbled this project together based on @Vortec4800 https://github.com/Vortec4800 's enormously helpful comments above. If you'd just like a working example to inspect - this should do. Code is in no way cleaned up or production ready - but it does illustrate a working token flow with initial grant and subsequent refreshes (thanks @Husqvik https://github.com/Husqvik !).
https://github.com/Kemmey/TeslaMFA
And HUGE THANK YOU to @timdorr https://github.com/timdorr for all your hard work on this - without this repo, my apps would not exist.
Nice job, I guess I shouldn't have been lazy and done something similar as this looks very similar to what I had put together :).
Did you run into the refresh token issue I described above? Have you gotten token refreshing working? That was the last piece of the puzzle for me.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/timdorr/tesla-api/issues/215#issuecomment-721144933, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABU4JYBR7AH67GMTPEECW43SOAGXPANCNFSM4Q4ZKKOQ .
@Vortec4800 look for @Husqvik 's comment about scope parameter. As soon as I manually added that, it worked perfectly. So yeah, refresh tokens work!
Oh cool, good looking out I totally missed that. Thank you!
Im trying to authenticate using a webapplication and not swift. Im stuck because when trying to set the callbackURL to my own callback URL I get a bad request "Invalid redirect URI" back from Tesla. How should I fix this?
I don't think you can, the redirect URL is fixed and can't be changed. In a native app we can look for that URL and catch it, but I don't know how you would do the same on a webapp.
You are correct @Vortec4800, have tried using an iframe to catch the data but Tesla does not allow running the authentication via an iframe: Refused to display 'https://auth.tesla.com/oauth2/v3/authorize?... in a frame because it set 'X-Frame-Options' to 'deny' To bad, hope Telsa will release a public version soon with possibility to set our own redirect_uri.
I was previously using the owner api through an Arduino WiFi Rev 2. Am I understanding correctly that there is currently no "easy" way to update the HTTPS Post call to get new tokens via password method? I tried with mfacode added as a header with no luck.
Deprecation as workaround: I also turned of MFA to regain functionality, again with no luck. Tried logging into tesla directly=>account locked from too many attempts. Reset and I'm in without MFA.
Question about "easy" update to HTTPS POST remains...
This is pretty scary - I hope they don't break Tesla owners API, i found when i entered the wrong username/password that I really got some mixed messages from API. To unlock yourself, go change your username/password to saem username/password on Tesla, then try again, and inspect user name / pass is correct, hope it helps!
On Mon, Nov 23, 2020 at 10:26 AM n-gineer notifications@github.com wrote:
I was previously using the owner api through an Arduino WiFi Rev 2. Am I understanding correctly that there is currently no "easy" way to update the HTTPS Post call to get new tokens via password method? I tried with mfacode added as a header with no luck.
Deprecation as workaround: I also turned of MFA to regain functionality, again with no luck. Tried logging into tesla directly=>account locked from too many attempts.
Question about "easy" update to HTTPS POST remains...
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/timdorr/tesla-api/issues/215#issuecomment-732306833, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABU4JYE62HJXLEGPJFPEWYLSRKLFDANCNFSM4Q4ZKKOQ .
This is pretty scary - I hope they don't break Tesla owners API, i found when i entered the wrong username/password that I really got some mixed messages from API. To unlock yourself, go change your username/password to saem username/password on Tesla, then try again, and inspect user name / pass is correct, hope it helps!
Thanks! that did help me get in with token generation.
Still hoping to find a long term option WITH MFA that doesn't require learning how to get a new language working alongside what I already have on the Arduino. Here's hoping!
If you get locked out, that's a separate system than the MFA one. That's always happened and something I've had to deal with occasionally while working on the API.
For the moment, even if you have MFA enabled, you can still access the Owner API with just your email and password. The password grant type has not yet been disabled or altered.
If you ever have auth problems, check your account on tesla.com as a first diagnostic step. If you're making a lot of bad auth requests while developing your software, then that's likely to come up regularly.
It sounds like the approach then is to take more a react and see approach. LIke once they lock down the 'password grant', I imagine a lot of softwares are going to break, including my nice automated powerwall system for managing our double peak energy rates. I will be curious if the group makes progress on like python or ruby or anything where we can see how to make specific http post with tokens. I imagine we're still waiting on the Tesla to publish some type of shared API token like you can get with other services as well.
On Mon, Nov 23, 2020 at 12:15 PM Tim Dorr notifications@github.com wrote:
If you get locked out, that's a separate system than the MFA one. That's always happened and something I've had to deal with occasionally while working on the API.
For the moment, even if you have MFA enabled, you can still access the Owner API with just your email and password. The password grant type has not yet been disabled or altered.
If you ever have auth problems, check your account on tesla.com as a first diagnostic step. If you're making a lot of bad auth requests while developing your software, then that's likely to come up regularly.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/timdorr/tesla-api/issues/215#issuecomment-732368748, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABU4JYBKHXRCLTOLAAWXR5LSRKYERANCNFSM4Q4ZKKOQ .
I second the request for a python example as I am a novice when it comes to Swift. I have made a few attempts however I must admit my understanding of oauth is a bit lacking.
Dan
I have update the TeslaSwift library based on some examples here. I'm not using OAuth2Swift and instead i do the oauth by myself, so the code is easier to read: https://github.com/jonasman/TeslaSwift
In essence you need to build the GET URL (https://auth.tesla.com/oauth2/v3/authorize) to open the page, the callback (https://auth.tesla.com/void/callback) will give you a code, no idea how to intercept the callback on web, but on the server should be doable. Relevant code to build the query params: https://github.com/jonasman/TeslaSwift/blob/master/Sources/TeslaSwift/Model/Authentication.swift
Then make a POST request to the token api (https://auth.tesla.com/oauth2/v3/token) with the code received to get the Auth Token.
Fantastic @jonasman - and good job on getting rid of dependencies in the solution! ❤️
@Kemmey thanks! Is your app using this lib?
@jonasman no, it is not. I wrote my own implementation before I found yours. And my implementation sucks as swift is not my main language. I might switch over at some point, but atm I'm stuck with my own mess :-D
Just implemented MFA and I see very long access and refresh tokens (around 800 byte each) compared to the 64 byte before. Which is odd but not a big deal, but the strange part is that the token is only 300 seconds valid before it needs refreshing, which is stupid in my eyes. Or do I need a different scope to obtain tokens which get a lifetime closer to what is was before (3888000 seconds). The scope I use currently is: "openid email offline_access".
@one4many: Did you implement MFA in a web solution or was it done using swift?
@one4many yeah, the MFA tokens have an extremely short lifespan, but on the other hand the refresh token doesn't seem to change very often. So I would co spider the refresh token as your main token, and just accept that most often, all actions require two http requests... which IS stupid, but it is what it is... Do let me know if you find a way to get a longer lived token!
@one4many: Did you implement MFA in a web solution or was it done using swift?
Ok. I wasn't very clear. I use username and password (my account is not MFA enabled yet) to create tokens with the new oauth interface. I get new tokens and they work, but they are ridiculously shot-lived compared to what they were before. This will create a lot of protocol overhead on my (server based) application.
I know a lot of folks are doing swift, just want to understand what the purpose is:
I assume its cause folks have IOS apps, and you assume your user exists there to insert their Username / Password on the Tesla Website. Can using this method, can you replace the user with a stored user name /password data store or variable?
I am wondering whether this method that is being proposed would be possible to do autmoated login / MFA token retrieval because we use or have applications that run automated that just look up password data store to do read/write actions for Tesla Powerwall like charge / discharge to control Tesla systems.
Is the method possible or is this whole methodology requiring the USER to be present?
On Mon, Nov 30, 2020 at 9:31 AM lannsjo notifications@github.com wrote:
@one4many https://github.com/one4many: Did you implement MFA in a web solution or was it done using swift?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/timdorr/tesla-api/issues/215#issuecomment-735891969, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABU4JYFBUIGJKOI5H6HLNK3SSPBR7ANCNFSM4Q4ZKKOQ .
Tesla app now uses a true oAuth2 protocol. specifically, the user no longer enters their credentials directly to the app; instead the user enters their credentials to a Tesla website directly.
This is the URL that is used to initiate oAuth: https://auth.tesla.com/oauth2/v3/authorize?client_id=ownerapi&code_challenge_method=S256&redirect_uri=https%3A%2F%2Fauth.tesla.com%2Fvoid%2Fcallback&locale=en&prompt=login&response_type=code&scope=email&state=xlni7Qb4ON540kwGBopz
The problem is that the redirect_uri is set to "https://auth.tesla.com/void/callback" and changing that will cause http 400 error.
Do you have plans to support the new oAuth2. Thanks!