Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document the new auth system #260

Closed
3 of 4 tasks
timdorr opened this issue Jan 30, 2021 · 107 comments
Closed
3 of 4 tasks

Document the new auth system #260

timdorr opened this issue Jan 30, 2021 · 107 comments

Comments

@timdorr
Copy link
Owner

timdorr commented Jan 30, 2021

This is a restart of #215, which has become quite noisy and off topic. If you are looking for help with an implementation or library/tool that uses the API, please use the Discussion board here on GitHub.

Tesla has switched to using a separate SSO service (auth.tesla.com) for their app and website. This replaces the previous password grant that was directly on the Owner API. They have also added MFA support with TOTP authenticators.

I've updated the Ruby library with support for login and token refresh, but need to add MFA support. The docs are completely missing as of this moment. Let's do this!

  • Document new login mechanism
    • Document MFA path
  • Document refreshing an access token
  • Implement MFA support in Ruby library
@timdorr
Copy link
Owner Author

timdorr commented Jan 30, 2021

I've updated for the new login mechanism: https://tesla-api.timdorr.com/api-basics/authentication

I'm still missing the MFA bits and am working on the refresh token process right now. Please let me know if there are any mistakes. PRs are welcome!

@alandtse
Copy link
Contributor

alandtse commented Jan 30, 2021

Thanks for documenting this. In my testing of step3, you can't use the base64 encoded version of code_verifier. Are you sure? When I tested with that version I ran into

{
"error": "invalid_request", 
"error_description": "Invalid code_verifier", 
"error_uri": "https://auth.tesla.com/error/reference/baabcc7-5c60-43b9-be7c-40a23f7129b1-1612044611898"}

I don't have the error if I use the unencoded version.

Repository owner deleted a comment from Juzzio Jan 30, 2021
@timdorr
Copy link
Owner Author

timdorr commented Jan 30, 2021

@alandtse Yep, that's an error on my part. Fixed it up now. Good catch!

@ekmekcioglu

This comment has been minimized.

@Dreamsorcerer
Copy link
Contributor

If I'm reading the steps correctly, refreshing tokens only works on the initial 5 min tokens? Which presumably requires refreshing within 10 mins of getting the token.

Is there no known way to refresh on a longer term basis? A 10 min refresh period is pretty much unusable for most applications, so we'd end up with the user needing to login again every 45 days, when the access token expires.

@timdorr
Copy link
Owner Author

timdorr commented Jan 30, 2021

There is only a 5 minute time limit on the bearer token, which you should be immediately exchanging for an access token on the Owner API. The refresh token is always long-lived and works until you use it, even after access token expiration.

@Dreamsorcerer
Copy link
Contributor

Perfect, thanks.

@alandtse
Copy link
Contributor

alandtse commented Jan 30, 2021

I'm getting an 401: {"response": "invalid_sso_token"} in step 4 when I use the access_token in step 3.

In step 3, I'm getting an additional id_token:

{"access_token": "eysnip", "refresh_token": "eysnip", "id_token": "eysnip", "expires_in": 300, "state": "snip", "token_type": "Bearer"}

Should we be discarding the id_token too? Or can it be used anywhere?

EDIT: I figured out my issue was the header wasn't being properly sent. So nothing wrong with the instructions. However, I always get id_token so that may need to be added.

@timdorr
Copy link
Owner Author

timdorr commented Jan 30, 2021

That's for OpenID Connect, which Tesla uses for their website. However, I only see that when refreshing a token. Are you using an authorization_code request_type?

@alandtse

This comment has been minimized.

@nabs-m

This comment has been minimized.

alandtse added a commit to alandtse/teslajsonpy that referenced this issue Jan 31, 2021
@alandtse

This comment has been minimized.

@benderl

This comment has been minimized.

@timdorr
Copy link
Owner Author

timdorr commented Jan 31, 2021

@nabilmaad You need to be POSTing, making the OAuth parameters as part of the query string, including all the form fields from the HTML as a form encoded POST body, and include the Cookie header. If you miss any of that, it will return the same HTML page and not the redirect.

@Dreamsorcerer
Copy link
Contributor

In step 1, it says an 86 character string. I think more precisely, this is 64 bytes of data in base64 encoding.

So, for example, in Python:

code_verifier = secrets.token_urlsafe(64)  # 64 bytes
print(len(code_verifier))  # 86 characters

Might be worth clarifying that.

@Dreamsorcerer
Copy link
Contributor

The redirect URL. Always "https://auth.tesla.com/void/callback"

I would hope that this is not "Always", and should in fact be anything you want.

This would then allow a standard oauth approach by web applications, so the user never needs to give their credentials to the application. This alternative flow would look like:

  1. Create state and other parameters. Redirect the user to that URL.
  2. On the callback URL (which the user will be redirected back to), get the passed parameters and verify the state.
  3. Continue with step 3/4 as before.

@minter

This comment has been minimized.

@baysinger
Copy link

baysinger commented Jan 31, 2021

@minter That URL takes me to the Telsa auth page, which requests username and password. But if you're already logged in, it might be taking you directly to the callback, which is an invalid URL. (The callback is supposed to be invalid. And AFAIK, you can't change it to anything else.)

If I'm already logged in, I get this flow:
image

So that might match what's happening for you. The 404 is totally normal.

@borgstrom
Copy link

borgstrom commented Jan 31, 2021

Hi @timdorr 👋

Your comment here #215 (comment) is incorrect.

The server does not discard state. It gives it back to you when you exchange your challenge code for a a bearer token.

You're correct that it is just recommended and not required as part of the spec. I also understand that right now the docs don't deal with MFA, and as such it means that the user is not actually involved with the auth flow right now so hijacking the flow is unlikely. However, once MFA is involved it means that consumers of this documentation will need to have a step involved where they prompt the user for an MFA code and maintain state themselves, at which point doing the state validation to prevent CSRF becomes much more critical.

I believe that the documentation should encourage users to validate the state they get back from exchanging the challenge code for the bearer token matches what they generated in all circumstances. Guidance should be to simply fail if the state does not match. For HTTP servers returning a 400 would be appropriate. For other use cases they can simply abort the auth process.

Edit: More info with pictures: https://www.youtube.com/watch?v=_xrhWLqX1j0

@nabs-m

This comment has been minimized.

@alandtse
Copy link
Contributor

alandtse commented Jan 31, 2021

@Dreamsorcerer

I would hope that this is not "Always", and should in fact be anything you want.

This would then allow a standard oauth approach by web applications, so the user never needs to give their credentials to the application. This alternative flow would look like:

I don't think you can change it. I'm testing whether I can change the redirect_uri and it looks like Tesla detects this.
image

I'd be happy to know I'm wrong though.

@lannsjo

This comment has been minimized.

@evogelpohl

This comment has been minimized.

@galulex

This comment has been minimized.

carlosonunez pushed a commit to carlosonunez/deprecated-tesla-oauth2-token-bot that referenced this issue May 9, 2021
Repository owner deleted a comment from pickenheim May 11, 2021
Repository owner deleted a comment from carlosonunez May 11, 2021
Repository owner deleted a comment from jnicolson May 11, 2021
Repository owner deleted a comment from JorenVos May 11, 2021
Repository owner deleted a comment from carlosonunez May 11, 2021
Repository owner deleted a comment from jdemeyer1 May 11, 2021
Repository owner deleted a comment from pickenheim May 11, 2021
Repository owner deleted a comment from pickenheim May 11, 2021
Repository owner deleted a comment from carlosonunez May 11, 2021
Repository owner deleted a comment from carlosonunez May 11, 2021
Repository owner deleted a comment from chrm-software May 11, 2021
Repository owner deleted a comment from jnicolson May 11, 2021
Repository owner deleted a comment from davidhodge May 11, 2021
Repository owner deleted a comment from carlosonunez May 11, 2021
Repository owner deleted a comment from chrm-software May 11, 2021
Repository owner deleted a comment from pickenheim May 11, 2021
Repository owner deleted a comment from carlosonunez May 11, 2021
Repository owner deleted a comment from spoonwzd May 11, 2021
Repository owner deleted a comment from epologee May 11, 2021
Repository owner deleted a comment from spoonwzd May 11, 2021
Repository owner deleted a comment from lannsjo May 11, 2021
@timdorr
Copy link
Owner Author

timdorr commented May 11, 2021

OK, I'm going to close this out since it's turning into support and implementation discussion. Please use the Discussion board here on GitHub for that sort of thing.

We'll discuss documenting MFA/TOTP in another issue.

@timdorr timdorr closed this as completed May 11, 2021
Repository owner locked as resolved and limited conversation to collaborators May 11, 2021
@timdorr timdorr unpinned this issue May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests