atcoder-cli 登录机制揭秘:acc login 如何安全保存会话而不泄露密码
【免费下载链接】atcoder-cliAtCoder command line tools项目地址: https://gitcode.com/gh_mirrors/at/atcoder-cli
atcoder-cli(命令行工具acc)是一个面向 AtCoder 算法竞赛的命令行工具,可一键创建项目目录、拉取题目与样例测试、提交代码。本文带你完整看懂它的登录机制:acc login为什么能把会话安全保存在本地,同时绝不存储你的密码。
一、什么是 atcoder-cli?
对于 AtCoder 竞赛选手来说,atcoder-cli提供的acc命令把重复劳动压缩成一行:
acc login # 登录 AtCoder acc new ABC300 # 创建竞赛项目目录 acc add # 拉取题目和样例测试 acc submit # 提交代码 acc session # 检查登录状态 acc logout # 清除本地会话其中登录相关功能由 src/commands.ts 中的login/logout/session三个命令实现,命令行入口定义在 src/cli/index.ts。那么问题来了:一个命令行程序,凭什么记住"你已登录"?它存的是密码吗?答案是:不是。
二、acc login 的完整流程:三步走
整个登录流程集中在 src/atcoder.ts 的login()方法中,可以拆成三步:
第 1 步:先确认是否已登录
登录前会调用checkSession()。它的技巧很巧妙:请求abc001竞赛的提交页,并禁用自动重定向。如果你已登录,页面正常返回;未登录时 AtCoder 会把你 302 重定向回竞赛首页——收到 302 就判定为未登录。
第 2 步:获取 CSRF 令牌
为防止伪造登录请求,AtCoder 的登录表单要求携带csrf_token。getCSRFToken()方法用 JSDOM 在内存中"打开"登录页 HTML,从隐藏表单里取出令牌——这一步刻意不使用任何已保存的 cookie,确保拿到全新的一次性令牌。
第 3 步:输入凭证并一次性提交
这是密码唯一"露面"的地方:
- 程序通过
inquirer在终端交互提示中读取用户名和密码,密码输入时显示为掩码,而不是出现在命令行参数里(命令行参数会被系统进程列表看到,这是常见的泄露途径); - 密码仅被拼进一次POST 请求发给 AtCoder,请求立即结束,字符串即被丢弃;
- 提交时同样禁用重定向,若跳转目标不是
/login页面,即判定登录成功。
源码中的注释直接点明了设计意图:あまりパスワード文字列を引き回したくない——"不想让密码字符串到处传递"(见 src/atcoder.ts)。
三、密码不落地:只保存会话 cookie 🍪
登录成功后,程序调用response.saveSession(),把AtCoder 响应头Set-Cookie中下发的会话 cookie提取出来(src/session.ts的makeSessionResponse),交给 cookie 管理器持久化。
关键设计在 src/cookie.ts:
- 它只认
key=value形式的 cookie 字符串数组,接口里根本没有存放密码的位置; - 通过
conf库把 cookie 写入标准配置目录下的session.json文件(configName: "session"),跨平台自动适配 Linux / macOS / Windows 的规范路径; - 运行
acc config-dir即可查看配置文件实际所在的目录(命令定义见 src/commands.ts)。
换句话说:本地文件里只有 cookie 这一把"房间钥匙",密码这把"身份证"从未离开过内存。后续所有请求(查题、拉样例、提交)都由 src/session.ts 的Session类自动把 cookie 附在请求头上,无需再次输入凭证。
四、事务机制:登录失败不会弄坏现有会话 ✨
Session.transaction()(src/session.ts)为整个登录过程套了一层"事务":
- 开始登录时,先克隆一份当前 cookie 副本;
- 登录过程中的一切 cookie 变更只发生在副本上;
- 只有登录成功,副本才被提升为正式会话并写入配置文件;
- 若凭证错误、网络中断,副本直接丢弃——旧会话完好无损。
这和数据库事务的"成功提交、失败回滚"思想如出一辙,保证任何一步出错都不会污染你已有的登录状态。
五、日常使用:检查与退出
| 操作 | 命令 | 发生了什么 |
|---|---|---|
| 检查登录状态 | acc session | 重访提交页,判断是否被 302 重定向 |
| 退出登录 | acc logout | 调用removeSession()清空 cookie 并覆写配置文件 |
| 其他命令自动登录 | 如acc contest | 未登录时自动触发一次login()交互流程 |
logout的实现(src/atcoder.ts)只是把本地session.json清空——注意它清除的是本地钥匙,不会让 AtCoder 服务端失效会话;若想彻底安全,还需在网页端退出登录。
六、安全设计小结
回顾acc login的整条链路,它的"不泄露密码"靠的是四道防线:
- 交互式掩码输入——密码不进命令行参数、不进日志;
- 一次性使用——密码仅用于单次 POST,用完即弃,全程不落盘;
- 只存 cookie——持久化层的数据结构里根本没有密码字段;
- 事务保护——失败即回滚,本地会话状态永远有效。
配合 CSRF 令牌防伪造、302 重定向探测登录态,atcoder-cli在命令行场景下实现了一套简洁而可靠的会话安全方案。想深入阅读,可以直接查看这三个核心文件:登录逻辑 src/atcoder.ts、会话事务 src/session.ts、cookie 持久化 src/cookie.ts,以及组件组装方式 src/di/index.ts。
【免费下载链接】atcoder-cliAtCoder command line tools项目地址: https://gitcode.com/gh_mirrors/at/atcoder-cli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考