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",
|
"Origin": "https://kite.zerodha.com",
|
||||||
})
|
})
|
||||||
|
|
||||||
# Step 1: Initialize OAuth session.
|
# Step 1: Initialize OAuth session and capture sess_id.
|
||||||
# allow_redirects=False is CRITICAL: the first 302 response sets kf_session
|
# sess_id is the OAuth session identifier that must be passed to twofa.
|
||||||
# with the OAuth context (api_key). Following the redirect updates kf_session
|
# Without it, Zerodha cannot link the twofa request to the OAuth app and
|
||||||
# to a plain web session (no OAuth), which causes twofa to return profile:{}
|
# returns profile:{} instead of redirect_url with request_token.
|
||||||
# instead of redirect_url with request_token.
|
connect_resp = session.get(
|
||||||
session.get(
|
|
||||||
f"https://kite.zerodha.com/connect/login?v=3&api_key={api_key}",
|
f"https://kite.zerodha.com/connect/login?v=3&api_key={api_key}",
|
||||||
timeout=15,
|
timeout=15,
|
||||||
allow_redirects=False,
|
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(
|
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,
|
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
|
# Step 2: Username + password
|
||||||
login_resp = session.post(
|
login_resp = session.post(
|
||||||
@ -223,20 +231,23 @@ def _perform_zerodha_login(
|
|||||||
|
|
||||||
request_id = login_data["data"]["request_id"]
|
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:
|
try:
|
||||||
import pyotp
|
import pyotp
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise AutoLoginError("pyotp is not installed on the server. Run: pip install pyotp==2.9.0")
|
raise AutoLoginError("pyotp is not installed on the server. Run: pip install pyotp==2.9.0")
|
||||||
totp_value = pyotp.TOTP(totp_secret).now()
|
totp_value = pyotp.TOTP(totp_secret).now()
|
||||||
twofa_resp = session.post(
|
twofa_data = {
|
||||||
KITE_TWOFA_ENDPOINT,
|
|
||||||
data={
|
|
||||||
"user_id": zerodha_login_id,
|
"user_id": zerodha_login_id,
|
||||||
"request_id": request_id,
|
"request_id": request_id,
|
||||||
"twofa_value": totp_value,
|
"twofa_value": totp_value,
|
||||||
"twofa_type": "totp",
|
"twofa_type": "totp",
|
||||||
},
|
}
|
||||||
|
if sess_id:
|
||||||
|
twofa_data["sess_id"] = sess_id
|
||||||
|
twofa_resp = session.post(
|
||||||
|
KITE_TWOFA_ENDPOINT,
|
||||||
|
data=twofa_data,
|
||||||
timeout=15,
|
timeout=15,
|
||||||
allow_redirects=False,
|
allow_redirects=False,
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user