[RedNote] 扫码和 Cookie 均成功后 check_login_status 仍可能误判未登录
Author: Dedean103Created Sep 5, 2026Updated Sep 5, 2026
问题描述
我使用的是 RedNote 海外账号。在本地分支增加 rednote.com backend 后,扫码和 Cookie 持久化已经成功,但 check_login_status 仍曾返回“未登录”。
进一步检查发现:
- Cookie 文件的修改时间会在扫码确认后更新;
.rednote.com下存在web_session和id_token(未修改 Cookie domain);- 使用同一份会话调用
search_feeds可以返回真实结果; - 因此至少在这种情况下,扫码和会话本身有效,问题集中在登录状态检测。
相关背景:#609、#699。#812 已经说明 RedNote 获取二维码应使用 /login;本 Issue 主要补充 check_login_status 的假阴性问题。
当前实现的问题
CheckLoginStatus 主要依赖单一 DOM selector:
.main-container .user .link-wrapper .channelRedNote 页面结构、加载时序或前端版本变化时,这个元素不一定能作为稳定的登录证据。Cookie 已经有效的情况下,单一 selector 仍可能导致假阴性。
复现步骤
- 使用 RedNote 海外账号,并让浏览器访问
rednote.com; - 从
https://www.rednote.com/login获取二维码; - 在 RedNote App 内扫码并确认;
- 确认 Cookie 文件已更新,且存在
.rednote.com的web_session/id_token; - 调用
check_login_status,可能仍返回未登录; - 使用相同会话调用只读业务接口(例如
search_feeds),可以正常返回结果。
建议方案
保留原有 selector,同时将 window.__INITIAL_STATE__.user 作为兼容性回退。只有在找到稳定用户身份字段且用户不是 guest 时,才把页面状态判定为已认证:
exists, _, err := pp.Has(`.main-container .user .link-wrapper .channel`)
if err != nil {
return false, errors.Wrap(err, "check login status failed")
}
state, stateErr := readLoginPageState(pp)
if stateErr != nil {
logrus.Warnf("读取登录页状态失败: %v", stateErr)
}
return exists || (stateErr == nil && state.Authenticated), nil页面状态读取的核心逻辑:
res, err := page.Eval(`() => {
const unwrap = value => {
if (!value || typeof value !== "object") return value;
if (value.value !== undefined) return value.value;
if (value._value !== undefined) return value._value;
return value;
};
const user = window.__INITIAL_STATE__ && window.__INITIAL_STATE__.user;
const candidates = user ? [user.userInfo, user.currentUser, user.me] : [];
const info = candidates
.map(unwrap)
.find(value => value && typeof value === "object") || null;
const guest = Boolean(info && info.guest === true);
const hasIdentity = Boolean(
info && (info.userId || info.user_id || info.nickname)
);
return JSON.stringify({
authenticated: Boolean(info && !guest && hasIdentity),
guest,
hasIdentity,
});
}`)这段读取应保持容错:__INITIAL_STATE__ 或候选字段缺失时,不应该让整个状态检查报错,也不应仅凭状态对象存在就判定登录。
本地验证结果
应用上述兼容检测并重新构建后:
check_login_status正确返回已登录;- 可以读取当前用户;
search_feeds在约 5.5 秒内返回真实搜索结果;- 再调用
get_login_qrcode会提示当前已登录。
脱敏后的诊断日志:
登录诊断: url=https://www.rednote.com/ sidebar=true authenticated_state=true guest=false user_identity=true login_button=false login_modal=false建议日志只记录上述布尔状态,不输出 Cookie value、token、user id 或昵称。
环境
- 上游基准 commit:
f4518665bbc546aebe3104d78aeb0867af9b720a - 账号:RedNote 海外账号
- 后端:本地分支通过
XHS_BACKEND=rednote选择https://www.rednote.com - 运行方式:Linux 上的本地二进制服务
如果这个方向符合项目计划,我可以继续把登录状态回退检测整理成独立 PR。
Source: xpzouying/xiaohongshu-mcp