会话与登录 / Sessions & Auth

登录与凭证

登录是自动化里最容易卡住的一步。这一页讲清楚三条稳妥的路子:直接用 snapshot → fill → click → wait 驱动登录表单、把账号收进 chrome-use auth 凭证保险库一键回填、以及处理 Sign in with Google / OAuth 与 Bitwarden 密码和 passkey。 目标是让 agent 用真实浏览器完成登录,而不是把密码留在 shell history 里。

基础登录流程

最直接的方式:打开登录页,用 snapshot -i 读出表单里的可交互元素, 挑出邮箱、密码、提交按钮对应的 @ref,逐个 fill 再 click,最后用 wait --url 确认已经跳到登录后的页面。

表单登录
$ chrome-use open https://app.example.com/login
$ chrome-use snapshot -i

# 从快照里挑出邮箱 / 密码 / 提交按钮的 @ref,然后:
$ chrome-use fill @e3 "user@example.com"
$ chrome-use fill @e4 "hunter2"
$ chrome-use click @e5
$ chrome-use wait --url "**/dashboard"
$ chrome-use snapshot -i
ℹ️ 为什么每次都要先 snapshot
@ref 是当前快照里的元素句柄,页面一变就可能失效。养成 先 snapshot -i 拿到当前 ref、再动作 的习惯,比硬编码选择器稳得多。 最后再 snapshot -i 一次,是为了确认真的登录成功(而不是停在报错的登录页)。
⚠️ 明文密码会泄漏
把密码直接写进命令里,它会留在 shell history、进程列表和日志里。只在一次性的本地调试里这么做; 任何敏感账号都应改用下面的 凭证保险库 或 Bitwarden,让密码永远不进命令行。

凭证保险库(auth save / login)

对于要反复登录的站点,把凭证一次性存进本地保险库,之后一条命令就能自动回填并提交。 --password-stdin 让密码从标准输入读取,不进 shell history。

auth save + auth login
# 保存一份凭证(密码从 stdin 读入,输入后按 Ctrl+D 结束)
$ chrome-use auth save my-app --url https://app.example.com/login \
    --username user@example.com --password-stdin

# 之后一条命令:打开登录页、回填、点击、等待表单完成
$ chrome-use auth login my-app
✅ 保险库 + Bitwarden 的分工
auth save 把凭证收进 chrome-use 的本地保险库;下面的 bwu 则从 Bitwarden 拉取。 两者可以配合:把密码留在 Bitwarden,登录时临时取用,凭证不落在命令行里。

Sign in with Google / OAuth

点站点自己的 Google 登录按钮,然后 snapshot -i:即使 GSI 的 “Continue as <user>” 按钮位于跨源 iframe 里,它也会拿到一个可点击的 @ref(Chrome 125+)。如果弹出的是账号选择弹窗,切到那个弹窗去驱动即可—— relay 会跟着你点击打开的弹窗走。

OAuth 跳转流程
# 触发 OAuth 流程
$ chrome-use open https://app.example.com/auth/google

# 等跳到 Google,再读一次快照
$ chrome-use wait --url "**/accounts.google.com**"
$ chrome-use snapshot -i

# 填 Google 账号,逐步推进
$ chrome-use fill @e1 "user@gmail.com"
$ chrome-use click @e2
$ chrome-use wait 2000
$ chrome-use snapshot -i
$ chrome-use fill @e3 "password"
$ chrome-use click @e4

# 等它跳回业务站点
$ chrome-use wait --url "**/app.example.com**"
ℹ️ 复用已登录的浏览器最省事
如果你本地的 Chrome 已经登进了 Google / 目标站点,与其重跑一遍 OAuth,不如直接 驱动那个真实 Chrome 或把它的会话状态存下来复用——详见 会话与持久化。

用 Bitwarden 密码与 passkey 登录

在登录页运行 auth login --bwu,从 bitwarden-use(0.7.0+)选择当前网站的账号。多个账号匹配时,先用上次在这个主机上登录成功的那个(只按 id 记在 ~/.chrome-use/bwu-items.json),其次用名字正好是站点主机名、或是它登录 iframe 主机名的那个(App Store Connect 的登录框是 idmsa.apple.com 的 iframe),选了哪个、为什么会写在 stderr 上;都没有时加 --item。site 适配器发现站点没登录时也会报 login wall:(见站点适配器)。某个站点第一次遇到登录墙时会问:这次用密码库登录、以后这个站点都自动登录,还是不登录也不再问;agent 调用时问题在 loginWall.ask 里,agent 要转问你。auth autologin status 查看决定(按站点存在 ~/.chrome-use/autologin.json),auth autologin always|never|off <host> 修改。密码、TOTP 和私钥通过 bwu run 传给子进程,不放进参数或输出。

扫码登录在手机确认后,有的网站还要再扫一次「安全验证」码。小红书会在页面上叠一个 Security Verification(安全验证)弹窗和新二维码(约一分钟过期),扫码状态轮询返回 HTTP 471,而底下的登录框仍显示「扫码成功 / 请在手机上确认」。这时每条命令都会提示 login verification: …,--json 里带 loginVerification(二维码在 qrSrc):把这个二维码(screenshot 或 qrSrc)交给用户用已登录的 App 扫,扫完之前不要 reload、打开别的页面或重新登录,否则验证作废。这期间自动登录和 site 的登录墙不会跳转。

在 --launch 浏览器中加 --passkey 只用密码库里的 passkey 登录(需 bwu 0.9.0+),不读取密码、TOTP 或自定义字段。普通密码登录也可用 passkey 完成两步验证。凭证装进标签页上的临时 WebAuthn 验证器,由 Chrome 签名,尝试结束后移除。安装期间,标签页的当前页面、已有的同进程与已连接的跨进程 iframe,以及之后打开的每个新文档都会拒绝 navigator.credentials.create(),结束后逐个恢复,有一处没恢复就报错。已知限制:在拦截之前就运行过的页面脚本(登录开始时已打开的页面)可能已保存原始函数或替换了 Proxy,可以绕过拦截;安装之后才连接的跨进程 iframe 不受拦截。这两种情况下的注册仍会被检测到并终止命令;检测到意外注册或无法确认清理时,命令报错。仅支持签名计数器为 0 的同步型 passkey;非零计数器需要写回密码库,当前会拒绝。扩展 relay 暂不支持 passkey:passkey-only 登录立即报错,普通登录继续走密码/TOTP。环境不支持 WebAuthn 时,普通登录回退到密码流程;passkey-only 登录报错。

auth login --bwu
$ curl -fsSL https://raw.githubusercontent.com/leeguooooo/bitwarden-use/main/install.sh | sh
$ chrome-use open https://github.com/login
$ chrome-use auth login --bwu --item github.com
$ chrome-use --session passkey-demo --launch open https://github.com/login
$ chrome-use --session passkey-demo --launch auth login --bwu --item github.com --passkey
$ chrome-use --session passkey-demo --launch snapshot -i

--no-submit 只填不提交,不读取 TOTP,也不安装 passkey 验证器;不能与 --passkey 同用。签名成功不代表网站接受了登录,需用 snapshot 或网站的已认证状态确认目标页面。

密码登录只有看到网站接受了才报成功:提交后等登录表单从页面上消失(页面加载完、连续两次读到),返回 signedIn: true 和 evidence;约 12 秒后表单还在就报 the sign-in was not confirmed,带上页面自己的提示。回车键是否到了页面也会检查:在你自己 Chrome 的后台标签页上,回车可能被 Chrome 接收却没到页面,这时什么都没提交,改点表单的登录按钮(submittedWith 会写明)。


处理两步验证(2FA)

遇到需要短信 / TOTP / 硬件密钥的第二步时,最省心的办法是让人来完成这一步,脚本在旁边等它跳转。 默认走扩展驱动你真实 Chrome 时窗口本来就可见,直接由你补第二步即可;把控制权正式交回用户用 session handoff(见 会话与持久化),交接后 agent 会拒绝对该会话的驱动命令,直到你交还。 只有在 --launch 另开浏览器时才需要 --headed 让那个窗口可见,再配一个较长的 --timeout 等登录后的 URL。

2FA:人工完成第二步
# 显示浏览器窗口,先用凭证登录
$ chrome-use open https://app.example.com/login --headed
$ chrome-use snapshot -i
$ chrome-use fill @e1 "user@example.com"
$ chrome-use fill @e2 "password123"
$ chrome-use click @e3

# 在窗口里手动完成 2FA,脚本等它跳转(最多 120s)
$ chrome-use wait --url "**/dashboard" --timeout 120000

HTTP Basic 与 Cookie 认证

不是所有站点都走表单。对 HTTP Basic Auth,导航前先设好凭证; 需要手动注入会话时,可以直接设置 cookie。

Basic Auth / cookie 注入
# HTTP Basic:导航前设置用户名 / 密码
$ chrome-use set credentials username password
$ chrome-use open https://protected.example.com/api

# 手动设置认证 cookie
$ chrome-use cookies set session_token "abc123xyz"
$ chrome-use open https://app.example.com/dashboard

登录一次,之后免登录

登录成本很高,别每次都重来。登录成功后把 cookie 和 localStorage 存成一份 state 文件,后续用 --state 加载即可以“已登录”状态启动。要跳过整套 OAuth / 2FA,这是最实用的一招。

state save / --state 复用
# 登录一次,保存 cookie + localStorage
$ chrome-use state save ./auth.json

# 之后的运行直接带着登录态启动
$ chrome-use --state ./auth.json open https://app.example.com
ℹ️ 想要自动保存 / 恢复?
用 --session-name(或 AGENT_BROWSER_SESSION_NAME)可以按名字自动存取会话, 不用手动管理文件。State 文件里含明文会话令牌——加密、gitignore、按名会话等细节都在 会话与持久化 里。

安全注意事项

登录不可避免地碰凭证和会话令牌。几条底线:

⚠️ state 文件 = 一把可复用的钥匙
一份保存下来的认证状态等同于一个活的登录会话——谁拿到都能冒充你。把它当密码看待: 最小权限、加密、及时销毁。别用共享目录,别塞进日志。