twikit icon indicating copy to clipboard operation
twikit copied to clipboard

Failed to log in

Open Curry-pad opened this issue 2 months ago • 9 comments

Following the 'Quick Example,' I wrote the login code as shown below. https://github.com/d60/twikit?tab=readme-ov-file#quick-example

  from twikit import Client
  import asyncio

  # Initialize client
  client = Client('ja')

  print("ユーザ名:",user_name)
  print("パスワード:",pass_word)
  
  async def main():
      await client.login(
          auth_info_1=user_name,
          auth_info_2=EMAIL,
          password=pass_word
          #cookies_file='cookies.json'
      )
  
  asyncio.run(main())

However, when I use

asyncio.run(main())

I get the following error.

Traceback (most recent call last):
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py", line 407, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/fastapi/applications.py", line 270, in __call__
    await super().__call__(scope, receive, send)
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/starlette/applications.py", line 124, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
    raise exc
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/starlette/routing.py", line 706, in __call__
    await route.handle(scope, receive, send)
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/starlette/routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
               ^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/fastapi/routing.py", line 235, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/fastapi/routing.py", line 163, in run_endpoint_function
    return await run_in_threadpool(dependant.call, **values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool
    return await anyio.to_thread.run_sync(func, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/anyio/to_thread.py", line 56, in run_sync
    return await get_async_backend().run_sync_in_worker_thread(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 2485, in run_sync_in_worker_thread
    return await future
           ^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 976, in run
    result = context.run(func, *args)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/ScrapingTwitter.py", line 95, in read_item
    return Twikit_Login.Twikit_Login(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/Twikit_Login.py", line 23, in Twikit_Login
    asyncio.run(main())
  File "/opt/render/project/python/Python-3.11.11/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/opt/render/project/python/Python-3.11.11/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/python/Python-3.11.11/lib/python3.11/asyncio/base_events.py", line 654, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/opt/render/project/src/Twikit_Login.py", line 16, in main
    await client.login(
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/twikit/client/client.py", line 343, in login
    await flow.execute_task(params={'flow_name': 'login'}, data={
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/twikit/utils.py", line 88, in execute_task
    response, _ = await self._client.v11.onboarding_task(
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/twikit/client/v11.py", line 90, in onboarding_task
    return await self.base.post(
           ^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/twikit/client/client.py", line 215, in post
    return await self.request('POST', url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/twikit/client/client.py", line 190, in request
    raise Forbidden(message, headers=response.headers)
twikit.errors.Forbidden: status: 403

When analyzing the HTML returned as a response, it appears as follows, and it seems that access is being blocked on the Twitter side.

Image

How can I resolve this error?

Curry-pad avatar Oct 07 '25 01:10 Curry-pad

Hi .


   def _init_http_client(self, proxy, **kwargs):
        ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
        cipher_suite = "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
        ssl_context.set_ciphers(cipher_suite)
        ssl_context.set_ecdh_curve("prime256v1")
        ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2
        ssl_context.maximum_version = ssl.TLSVersion.TLSv1_3
        kwargs["verify"] = ssl_context
        headers = kwargs.pop("headers", {})
        headers["User-Agent"] = self._user_agent

        return AsyncClient(proxy=proxy, headers=headers, **kwargs)

i replace init http client, add ssl context and user-agent and remove proxy property(Since there is a change in ssl) from in Client class. @propeprty def proxy....

This helped me bypass cloudflare. Some requests go through, but now I get a different error.

Could not log you in now. Please try again later. g;176001657209663103:-1760016572516:QLC8LubDF9irDeYMOMB1GZT2:1 .

Has anyone encountered this? Twitter uses Castle Antibot, I tried to bypass it, but it doesn't seem to help.

mrSakur avatar Oct 09 '25 13:10 mrSakur

Under the hood they have implemented castle.io token that fingerprints your environment. If you notice in original request in the browser you will see castle_token. When that token is invalid it gives you the error you're facing. The solution? There isn't one available yet. A guy here have reversed the castle.io token generation for Twitter but that's outdated and no longer works.

Hi .


   def _init_http_client(self, proxy, **kwargs):
        ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
        cipher_suite = "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
        ssl_context.set_ciphers(cipher_suite)
        ssl_context.set_ecdh_curve("prime256v1")
        ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2
        ssl_context.maximum_version = ssl.TLSVersion.TLSv1_3
        kwargs["verify"] = ssl_context
        headers = kwargs.pop("headers", {})
        headers["User-Agent"] = self._user_agent

        return AsyncClient(proxy=proxy, headers=headers, **kwargs)

i replace init http client, add ssl context and user-agent and remove proxy property(Since there is a change in ssl) from in Client class. @propeprty def proxy....

This helped me bypass cloudflare. Some requests go through, but now I get a different error.

Could not log you in now. Please try again later. g;176001657209663103:-1760016572516:QLC8LubDF9irDeYMOMB1GZT2:1 .

Has anyone encountered this? Twitter uses Castle Antibot, I tried to bypass it, but it doesn't seem to help.

runetech0 avatar Oct 09 '25 13:10 runetech0

Yeah they are filtering User-Agents like python-httpx/* (twikit is defaulting to this,) curl/*, etc, using a regular browser user_agent progresses through to the username task. The 400 error seems to be related to the Bearer token and X-Client-Transaction-Id again.

This has been a problem lately with other tools as well.

Replacing the old TOKEN constant in constants.py and client/v11.py (L83) to: AAAAAAAAAAAAAAAAAAAAAFQODgEAAAAAVHTp76lzh3rFzcHbmHVvQxYYpTw%3DckAlMINMjmCwxUcaXbAN4XqJVdgMJaHqNOFgPMK0zN1qLqLQCF will enable you to login successfully until the x-client-transation process can be addressed. I'm still not entirely sure how this effects other elements of the tool but I've pretty much used this token exclusively for everything else now without issues.


Something like this works for me: https://github.com/cmj/twikit/commit/dc28f9ca062fd5c3e0213c241ae2f10e3bc95219

Again, more probably needs to be cleaned up like the use of X-Client-Transaction-Id, but that should be a working hotfix.

cmj avatar Oct 10 '25 14:10 cmj

Has anyone solved this problem? How can we resolve the 403 error, bypass Cloudflare verification, or are there any other recommended frameworks?

LF-Wow avatar Oct 11 '25 01:10 LF-Wow

Might want to also look at using cloudscraper. It was just used to resolve another cloudflare issue: https://github.com/zedeus/nitter/issues/1289#issuecomment-3393561953

I should note Nitter uses the Bearer token I posted above.

cmj avatar Oct 11 '25 22:10 cmj

https://github.com/dsekz/twitter-x-xp-forwarded-for-header/issues/4#issuecomment-3393878937 https://github.com/d60/twikit/pull/393

heysurfer avatar Oct 12 '25 03:10 heysurfer

I tried implementing the castle_token generation API developed by @heysurfer into my tweepy-authlib, but unfortunately I'm still getting a 399 error from LoginEnterUserIdentifierSSO. It's possible that there's an issue with my implementation, but the problem persists even though I'm generating and attaching an X-XP-Forwarded-For header and using curl-cffi. ...However, I found that changing the Bearer token used when accessing /1.1/onboarding/task.json to the one used by the old TweetDeck allowed me to log in successfully. I'm not sure why, but this seems to be working for now.

tsukumijima avatar Oct 22 '25 01:10 tsukumijima

I'm just starting to use Twikit. But I couldn't log in. I'm getting the same error.

emraherkol avatar Oct 26 '25 19:10 emraherkol

I have successfully reverse engineered castle_token.

gugugudo avatar Nov 14 '25 16:11 gugugudo