Fix auto-login: pass sess_id to twofa to link request to OAuth app
The sess_id from the connect/login redirect is Zerodha's OAuth session
identifier. Without it in the twofa POST, Zerodha returns profile:{}
(regular web login) instead of redirect_url with request_token.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e447a39912
commit
9d1126b84d
@ -187,20 +187,28 @@ def _perform_zerodha_login(
|
||||
"Origin": "https://kite.zerodha.com",
|
||||
})
|
||||
|
||||
# Step 1: Initialize OAuth session.
|
||||
# allow_redirects=False is CRITICAL: the first 302 response sets kf_session
|
||||
# with the OAuth context (api_key). Following the redirect updates kf_session
|
||||
# to a plain web session (no OAuth), which causes twofa to return profile:{}
|
||||
# instead of redirect_url with request_token.
|
||||
session.get(
|
||||
# Step 1: Initialize OAuth session and capture sess_id.
|
||||
# sess_id is the OAuth session identifier that must be passed to twofa.
|
||||
# Without it, Zerodha cannot link the twofa request to the OAuth app and
|
||||
# returns profile:{} instead of redirect_url with request_token.
|
||||
connect_resp = session.get(
|
||||
f"https://kite.zerodha.com/connect/login?v=3&api_key={api_key}",
|
||||
timeout=15,
|
||||
allow_redirects=False,
|
||||
)
|
||||
# Extract sess_id from the Location header redirect URL
|
||||
connect_location = connect_resp.headers.get("Location", "")
|
||||
sess_id = None
|
||||
if "sess_id=" in connect_location:
|
||||
sess_id = parse_qs(urlparse(connect_location).query).get("sess_id", [None])[0]
|
||||
print(
|
||||
f"[AUTO-LOGIN-DEBUG] connect cookies={list(session.cookies.keys())}",
|
||||
f"[AUTO-LOGIN-DEBUG] connect status={connect_resp.status_code} "
|
||||
f"sess_id={sess_id} cookies={list(session.cookies.keys())}",
|
||||
flush=True,
|
||||
)
|
||||
# Follow the redirect so the server registers the sess_id against kf_session
|
||||
if connect_location:
|
||||
session.get(connect_location, timeout=15, allow_redirects=True)
|
||||
|
||||
# Step 2: Username + password
|
||||
login_resp = session.post(
|
||||
@ -223,20 +231,23 @@ def _perform_zerodha_login(
|
||||
|
||||
request_id = login_data["data"]["request_id"]
|
||||
|
||||
# Step 3: TOTP
|
||||
# Step 3: TOTP — include sess_id so Zerodha links this to the OAuth app
|
||||
try:
|
||||
import pyotp
|
||||
except ImportError:
|
||||
raise AutoLoginError("pyotp is not installed on the server. Run: pip install pyotp==2.9.0")
|
||||
totp_value = pyotp.TOTP(totp_secret).now()
|
||||
twofa_resp = session.post(
|
||||
KITE_TWOFA_ENDPOINT,
|
||||
data={
|
||||
twofa_data = {
|
||||
"user_id": zerodha_login_id,
|
||||
"request_id": request_id,
|
||||
"twofa_value": totp_value,
|
||||
"twofa_type": "totp",
|
||||
},
|
||||
}
|
||||
if sess_id:
|
||||
twofa_data["sess_id"] = sess_id
|
||||
twofa_resp = session.post(
|
||||
KITE_TWOFA_ENDPOINT,
|
||||
data=twofa_data,
|
||||
timeout=15,
|
||||
allow_redirects=False,
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user