{"record":{"id":"ad8a499f51232f0d","repo":"jackwener/OpenCLI","slug":"ctrip-login-uid-cookie-absent-after-navigation","errorCode":null,"errorMessage":"Ctrip login_uid cookie absent after navigation","messagePattern":"Ctrip login_uid cookie absent after navigation","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/ctrip/auth.js","lineNumber":20,"sourceCode":"import { registerSiteAuthCommands } from '../_shared/site-auth.js';\n\nasync function hasCtripLoginUid(page) {\n  const cookies = await page.getCookies({ url: 'https://www.ctrip.com' });\n  const loginUid = cookies.find(c => c.name === 'login_uid');\n  return Boolean(loginUid && loginUid.value);\n}\n\nasync function verifyCtripIdentity(page) {\n  if (!await hasCtripLoginUid(page)) {\n    throw new AuthRequiredError('ctrip.com', 'Ctrip login_uid cookie missing — anonymous');\n  }\n  await page.goto('https://my.ctrip.com/myinfo/MyInfoIndex.aspx');\n  await page.wait(2);\n  const cookies = await page.getCookies({ url: 'https://www.ctrip.com' });\n  const cookieMap = Object.fromEntries(cookies.map(c => [c.name, c.value]));\n  const loginUid = cookieMap['login_uid'] || '';\n  if (!loginUid) {\n    throw new AuthRequiredError('ctrip.com', 'Ctrip login_uid cookie absent after navigation');\n  }\n  const aheadRaw = cookieMap['AHeadUserInfo'] || '';\n  const params = new URLSearchParams(aheadRaw);\n  const userNameRaw = params.get('UserName') || '';\n  let userName = '';\n  if (userNameRaw) {\n    try {\n      userName = decodeURIComponent(userNameRaw);\n    } catch {\n      userName = userNameRaw;\n    }\n  }\n  const vipGrade = params.get('VipGrade') || '';\n  return { user_id: loginUid, name: userName, vip_grade: vipGrade };\n}\n\nregisterSiteAuthCommands({\n  site: 'ctrip',","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/ctrip/auth.js#L2-L38","documentation":"verifyCtripIdentity navigates to my.ctrip.com/myinfo/MyInfoIndex.aspx to confirm the session, then re-reads cookies for www.ctrip.com. If login_uid disappeared after that navigation (it was present in the quick check), it throws AuthRequiredError — the session is effectively invalid even though a cookie existed moments earlier.","triggerScenarios":"`ctrip login --wait`/verify when the login_uid cookie existed before the myinfo navigation but the server invalidated the session during it — e.g. expired session, kicked-out concurrent login, or the profile page redirecting to a login flow that clears cookies.","commonSituations":"Stale cookie from a long-ago login that the server rejects; logging in from another device invalidates the old session; Ctrip rotating/clearing login_uid on untrusted-IP access; the myinfo page failing to load fully within the 2s wait.","solutions":["Re-run the login flow (`ctrip login`) to establish a fresh session, then verify again.","Log out other devices/sessions on Ctrip if concurrent-login invalidation is suspected.","Retry — if the myinfo page was slow, the cookie may reappear once loaded.","Check network/IP reputation (VPN/datacenter IP) that could cause Ctrip to drop the session."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// verify the session is healthy before dependent commands\nconst identity = await opencli.ctrip.whoami().catch(() => null);\nif (!identity) await opencli.ctrip.login();","typeGuard":null,"tryCatchPattern":"try {\n  const identity = await opencli.ctrip.whoami();\n} catch (err) {\n  if (err.name === 'AuthRequiredError' && /absent after navigation/i.test(err.message)) {\n    await opencli.ctrip.login(); // fresh session, then retry\n  } else throw err;\n}","preventionTips":["Re-login when sessions are old; Ctrip expires sessions server-side.","Avoid concurrent logins on multiple devices with the same account.","Retry once before concluding the session is dead (page may have loaded slowly).","Use a stable, reputable IP; Ctrip drops sessions from suspicious addresses."],"tags":["auth-required","session-expired","cookies","ctrip"],"backgroundTag":"session-cookie-invalidated","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}