"""Extract serviceToken using passToken and save to ~/.mi.token""" import asyncio, json, base64, hashlib, secrets, string from pathlib import Path from aiohttp import ClientSession PASS_TOKEN = "V1:DXmurwq2/R1BHTELu6obCYX7Rq/4OZACAywwHdbXYQdJStLxyGwZzcsUMnk6tnJfQvY6HNI1whU+hcSk8uE2Odjpi89ldPfcJTiZ9Tzm4tcaXJakpJa4yk+FuEFO3bqcF941B0MznsQT+HGEETHP/CHAKpKlxavwIZNwuH2TYJH9gFMEhxzKf5vDASX86lyVPUjXOZF1e+qN0+62zJU6HTorL2fiYXYWL+ikS3mKCHQCaB/+NjqLEGohcmXsCKEEyE6ImJbk6nnQB/EobhcK6GhE8zHSL8MAXhppsfhCt+flp0ymq5ntBGnqHshdySMQaQxklVv8JNvVCr5FdZs4kQ==" USER_ID = "1136458602" async def main(): async with ClientSession() as s: headers = {"User-Agent": "Mozilla/5.0"} device_id = "".join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(16)) cookies = { "sdkVersion": "3.9", "deviceId": device_id, "userId": USER_ID, "passToken": PASS_TOKEN, } url = "https://account.xiaomi.com/pass/serviceLogin?sid=micoapi&_json=true" async with s.get(url, cookies=cookies, headers=headers) as r: raw = await r.text() data = json.loads(raw[11:]) print(f"serviceLogin code: {data.get('code')}") ssecurity = data["ssecurity"] location = data["location"] nonce = str(data["nonce"]) new_pass = data.get("passToken", PASS_TOKEN) nsec = f"nonce={nonce}&{ssecurity}" client_sign = base64.b64encode(hashlib.sha1(nsec.encode()).digest()).decode() sts_url = f"{location}&clientSign={client_sign}" async with s.get(sts_url, headers=headers) as r2: service_token = r2.cookies.get("serviceToken", "").value token = { "deviceId": device_id, "userId": USER_ID, "passToken": new_pass, "micoapi": [ssecurity, service_token], } token_path = Path.home() / ".mi.token" token_path.write_text(json.dumps(token, ensure_ascii=False, indent=2), encoding="utf-8") print(f"Token saved to {token_path}") print(f" userId: {USER_ID}") print(f" passToken: OK") print(f" ssecurity: OK") print(f" serviceToken: OK ({service_token[:30]}...)") asyncio.run(main())