From dc663a129cea4a80eed4c590e1e989b8394f520c Mon Sep 17 00:00:00 2001 From: Thigazhezhilan J Date: Tue, 26 May 2026 21:28:09 +0530 Subject: [PATCH] Fix auto-login: remove Referer header, add Accept/Origin headers Referer on POST was causing Zerodha to reject login with Invalid username. Add Accept, Accept-Language, Origin headers for proper browser-like requests. Keep redirect_url body check for twofa. Add login step debug logging. Co-Authored-By: Claude Sonnet 4.6 --- backend/app/services/auto_login_service.py | 31 ++++++++++------------ 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/backend/app/services/auto_login_service.py b/backend/app/services/auto_login_service.py index 9bfa014..28b31b6 100644 --- a/backend/app/services/auto_login_service.py +++ b/backend/app/services/auto_login_service.py @@ -176,44 +176,42 @@ def _perform_zerodha_login( ) -> dict: """Automates Zerodha login and returns session data with access_token.""" session = requests.Session() - # Use a real browser UA; do NOT set X-Kite-Version here — that header is - # for the Kite Connect REST API, not the web login endpoints, and confuses - # Zerodha's routing so it returns a plain profile response instead of an - # OAuth redirect_url. session.headers.update({ "User-Agent": ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/124.0.0.0 Safari/537.36" ), + "Accept": "application/json, text/plain, */*", + "Accept-Language": "en-US,en;q=0.9", + "Origin": "https://kite.zerodha.com", }) - # Step 1: Initialize OAuth session. - # Use allow_redirects=False so we capture the Set-Cookie from the first - # response before any redirect overwrites/clears the OAuth context cookie. + # Step 1: Initialize OAuth session so Zerodha associates this session with + # the api_key before we submit credentials. connect_resp = session.get( f"https://kite.zerodha.com/connect/login?v=3&api_key={api_key}", timeout=15, - allow_redirects=False, + allow_redirects=True, ) print( - f"[AUTO-LOGIN-DEBUG] connect status={connect_resp.status_code} " - f"location={connect_resp.headers.get('Location', 'NONE')} " + f"[AUTO-LOGIN-DEBUG] connect final_url={connect_resp.url} " + f"status={connect_resp.status_code} " f"cookies={list(session.cookies.keys())}", flush=True, ) - # Follow the redirect to the login page so the full OAuth init completes - redirect_to = connect_resp.headers.get("Location", "") - if connect_resp.status_code in (301, 302, 303, 307, 308) and redirect_to: - session.get(redirect_to, timeout=15, allow_redirects=True) # Step 2: Username + password login_resp = session.post( KITE_LOGIN_ENDPOINT, data={"user_id": zerodha_login_id, "password": password}, - headers={"Referer": "https://kite.zerodha.com/login"}, timeout=15, ) + print( + f"[AUTO-LOGIN-DEBUG] login status={login_resp.status_code} " + f"body={login_resp.text[:300]}", + flush=True, + ) try: login_data = login_resp.json() except Exception: @@ -238,7 +236,6 @@ def _perform_zerodha_login( "twofa_value": totp_value, "twofa_type": "totp", }, - headers={"Referer": "https://kite.zerodha.com/login"}, timeout=15, allow_redirects=False, ) @@ -250,7 +247,7 @@ def _perform_zerodha_login( ) # Step 4: Extract request_token. - # Modern Zerodha (SPA): returns 200 JSON with data.redirect_url containing request_token. + # Modern Zerodha (SPA): returns 200 JSON with data.redirect_url. # Older behavior: 302 Location header redirect. request_token = None