Automated script setup to autogen token when it expires reported error to my email.
Thx for the info. Trying to sort through. Initial call to /oauth2/v3/authorize is showing Bad Request with no hidden fields. Is the GET supposed to be sent with any params? Using curl.
Yeah I'm not 100% sure how you recreate the CURL call.
To be successful , you really need a couple of items, and if you go to this form, you could capture network traffic and see it all happening:
Tesla SSO – Login
But the first piece is to first generate a URL, which the challenge etc:
Those URLs looking something like:
Tesla SSO - Sign In
Authentication
-first step is to generate URL parameters:
https://auth.tesla.com/oauth2/v3/authorize , then add ? and these URL params:
Prerequisites:
- Use a HTTP client with a cookie jar.
- Generate 86 random bytes to act as the challenge, encode as base 64 (URL variant). Let's call this challenge
- Create a sha256 sum of those 86 bytes, encode as base 64 (URL variant). Let's call this sum.
- Generate a random string, it can be anything at all. Let's call this state.
Steps
Note: Any values surrounded by { and } are variables. Such {sum} is a reference to a variable we declared earlier.
Authenticate
Send a request where code_challenge is equal to sum.
GET
https://auth.tesla.com/oauth2/v3/authorize
With paramters below the sample call looks like:
https://auth.tesla.com/oauth2/v3/authorize?client_id=ownerapi&code_challenge={sum} and son on.
client_id = ownerapi
code_challenge = {sum}
code_challenge_method = S256
redirect_uri =
Tesla SSO – Page Not Found
response_type = code
scope = openid email offline_access
state = {state}
Build a new map of URL values and pre-populate with two fields, identity and credential which are the username and password respectively.
{
identity: [{username}],
credential: [{password}]
}
Using the response from our last request, find all input[type=hidden] tags and add their respective name and value attributes to the map. The map should eventually look like:
{
identity: [{username}],
credential: [{password}],
_csrf: ['yj3XoCPV-rubeQEjoc8J9zDCihRFzAj21h6k'],
_phase: ['authenticate'],
_process: ['1'],
cancel: [],
transaction_id: ['iCeMaQlX'],
]
Now we can make another request. Encode the map to the request body as a URL encoded form.
POST
https://auth.tesla.com/oauth2/v3/authorize
Content-Type: application/x-www-form-urlencoded
client_id = ownerapi
code_challenge = {sum}
code_challenge_method = S256
redirect_uri =
Tesla SSO – Page Not Found
response_type = code
scope = openid email offline_access
state = {state}
This request will return status 302 (Found). Do not follow it. Parse the location of the redirect, and get the URL value called code.
Access token
Now we have a code, we can get an access token. We need to make another JSON request.
{
grant_type: 'authorization_code',
client_id: 'ownerap',
code_verifier: {challenge},
code: {code},
redirect_uri: '
Tesla SSO – Page Not Found',
}
POST
https://auth.tesla.com/oauth2/v3/token
Content-Type: application/json
We'll then get back a response body with three tokens.
{
access_token: '...'
refresh_token: '...',
id_token: '...',
expires_in: 300,
state: {state},
token_type: 'Bearer'
}
Exchange token
We can now exchange our access token for a long-lived token.
{
grant_type: 'urn:ietf
arams
auth:grant-type:jwt-bearer',
client_id: '81527cff06843c8634fdc09e8ac0abefb46ac849f38fe1e431c2ef2106796384',
client_secret: 'c7257eb71a564034f9419ee651c7d0e5f7aa6bfbd18bafb5c5c033b093bb2fa3'
}
POST
https://owner-api.teslamotors.com/oauth/token
Authorization: Bearer {access_token}
Content-Type: application/json
The response will contain your long-lived access token.
{
access_token: '...'
}