tdorssers / TeslaPy

A Python module to use the Tesla Motors Owner API
MIT License
374 stars 84 forks source link

Captcha issue #29

Closed gaardiolor closed 3 years ago

gaardiolor commented 3 years ago

Hello,

Looks like tesla changed something.

Traceback (most recent call last):
  File "/usr/local/scripts/teslacli/teslacli.py", line 40, in <module>
    main()
  File "/usr/local/scripts/teslacli/teslacli.py", line 31, in main
    tesla = fetch_tesla()
  File "/usr/local/scripts/teslacli/teslacli.py", line 16, in fetch_tesla
    tesla.fetch_token()
  File "/usr/local/scripts/teslacli/venv/lib/python3.9/site-packages/teslapy/__init__.py", line 210, in fetch_token
    raise ValueError('. '.join(msgs))
ValueError: Credentials rejected. Captcha is required. Captcha does not match

The first GET to oauth2/v3/authorize does not ask for a captcha, but after POST'ing username / password it rejects the login, and a new form is presented. Looks identical to the previous, but now a captcha is requested. teslapy doesn't handle this correctly.

Had to copy this in (__init__.py after line 198) to check for it:

        form = HTMLForm(response.text)
        # Retrieve captcha image if required
        if 'captcha' in form:
            response = oauth.get(self.sso_base + 'captcha')
            response.raise_for_status()  # Raise HTTPError, if one occurred
            form['captcha'] = self.captcha_solver(response.content)
            if not form['captcha']:
                raise ValueError('Missing captcha response')
            # Submit login credentials to get authorization code through redirect
            form.update({'identity': self.email, 'credential': self.password})
            response = oauth.post(self.sso_base + 'oauth2/v3/authorize',
                                  data=form, allow_redirects=False)
dawiinci commented 3 years ago

24

tdorssers commented 3 years ago

Please give the fix in ebcef52 a try!

marcone commented 3 years ago

Is there a way to avoid triggering the captcha altogether? When I use cli.py it asks for a captcha, but when I sign in with the Tesla app it does not. (edit: to be clear: this is with the latest code from github)

omaliphant commented 3 years ago

@tdorssers i still seem to have an issue where the captcha doesnt save the svg file to my directory and never prompts me for the captcha response?

im using the:

`def solveCaptcha(svg):

    with open('captcha.svg', 'wb') as f:

        f.write(svg)

        f.close()

    return input('Captcha: ')`

with:

`def teslapyStartSession(creds):

    with teslapy.Tesla(creds[0], creds[2], lambda: 'XXXXXX') as tesla:

        tesla.captcha_solver = solveCaptcha

        tesla.fetch_token()

    return tesla`

is this correct?

dawiinci commented 3 years ago

Please give the fix in ebcef52 a try!

Unfortunately it still asks for a Captcha and opens the browser.

   Script Error                    tesla_connect.py: EOF when reading a line
   Script Error                    Exception Traceback (most recent call shown last):

     tesla_connect.py, line 18, at top level
     File "/Users/server/Library/Python/2.7/lib/python/site-packages/teslapy/__init__.py", line 205, in fetch_token
       form['captcha'] = self.captcha_solver(response.content)
     File "/Users/server/Library/Python/2.7/lib/python/site-packages/teslapy/__init__.py", line 319, in _solve_captcha
       return input('Captcha: ')
EOFError: EOF when reading a line

I just replaced the three files in teslapy folder.

tdorssers commented 3 years ago

I don't know why the auth server asks for a captcha, probably because it recognizes a foreign app logging in.

tdorssers commented 3 years ago

@tdorssers i still seem to have an issue where the captcha doesnt save the svg file to my directory and never prompts me for the captcha response?

im using the:

`def solveCaptcha(svg):
    with open('captcha.svg', 'wb') as f:
        f.write(svg)
        f.close()
    return input('Captcha: ')`

with:

`def teslapyStartSession(creds):
    with teslapy.Tesla(creds[0], creds[2], lambda: 'XXXXXX') as tesla:
        tesla.captcha_solver = solveCaptcha
        tesla.fetch_token()
    return tesla`

is this correct?

Does this occur using version ebcef52? I haven't released a new version to pypi. Do you get any tracebacks?

tdorssers commented 3 years ago

Is there a way to avoid triggering the captcha altogether? When I use cli.py it asks for a captcha, but when I sign in with the Tesla app it does not. (edit: to be clear: this is with the latest code from github)

I haven't found a way yet, maybe it has something to do with the useragent or some other properties that are recognized by the auth server.

gaardiolor commented 3 years ago

@tdorssers https://github.com/tdorssers/TeslaPy/commit/ebcef529f9a7754d3b025caef8721327cf2cb3a6 works, no more tracebacks. Thanks!

HildisviniOttar commented 3 years ago

If you reverse proxy the native Tesla iOS app through Charles, API calls works with the Bearer tokens.
However if you logout and try to login again, it fails and shows an NSURLConnection error. Remove proxy and it works fine. They must be hard-coding a trusted certificate in-app that Tesla API requires for initial primary app auth.

Interestingly - I wonder if the native iOS app token can be used by teslapy for "permanent" auth token. 🤔