2026-09-18 10:02:00 +08:00
2026-09-14 17:51:40 +08:00
2026-09-14 13:45:17 +08:00
2026-09-18 09:41:27 +08:00
2026-09-18 10:02:00 +08:00
2026-09-17 23:00:47 +08:00
2026-09-14 13:45:17 +08:00
2026-09-14 15:13:10 +08:00
2026-09-17 23:00:47 +08:00
2026-09-18 09:41:27 +08:00
2026-09-18 09:41:27 +08:00
2026-09-18 09:50:59 +08:00
2026-09-18 10:02:00 +08:00
2026-09-17 23:00:47 +08:00
2026-09-18 09:41:27 +08:00

Auto Login Manager

针对特定域名自动填充用户名 / 密码并完成登录,支持多环境(个人 / 测试 / 生产)管理与本地加密存储。

Chrome Manifest V3 扩展。所有凭据只保存在本机,不上传任何服务器,无网络请求、无统计分析、无第三方 SDK。

功能特性

配置与匹配

  • 域名规则支持精确匹配、通配符(*.example.com、api.*.example.com)与路径(oa.com/login/*)
  • 多环境隔离(个人 / 测试 / 生产…),同一域名在不同环境下保存不同账号,命中多个环境时弹窗选择
  • 支持拖拽排序、启用 / 禁用单条配置、按域名 / 用户名 / 别名搜索
  • 从浏览器书签批量导入域名

填充与登录

  • 自动填充用户名与密码,可选择是否自动点击登录
  • 三级降级探测字段:显式选择器 → 关键词启发式(name / id / placeholder / autocomplete)→ 全量兜底
  • 支持 Shadow DOM 穿透(组件库封装的登录框也能识别)
  • 支持 iframe 内的登录表单(如 SSO 内嵌登录页):脚本注入所有帧,各帧按自己的地址匹配配置;iframe 内命中多个环境时不弹浮窗(避免被裁切),改用当前激活环境
  • 针对 SPA 的延迟重试:表单晚于脚本渲染时,最长 30 秒内持续重试。重试按 DOM 变更门控并逐步退避,且会监听已发现的 Shadow Root,因此既不会在大页面空转,也不会漏掉组件内部后渲染的登录框
  • 检测到验证码(reCAPTCHA / hCaptcha / 滑块 / 图形码)时只填充、不自动提交,并提示手动完成
  • 同一域名连续自动提交 3 次后暂停自动提交(仍填充),5 分钟后自动恢复;检测到登录成功(登录框消失或已离开匹配地址)会立即清零计数,达到上限时页面上会给出提示
  • 手动填充:在当前页面按需注入并填充,无需预先打开对应页面

安全与数据

  • 保险库加密:PBKDF2-SHA256(20 万次迭代)派生密钥 + AES-GCM-256 整库加密
  • 派生密钥为不可导出(extractable: false)的 CryptoKey,以密钥句柄形式存于 IndexedDB;主口令不写入任何存储
  • 解锁期间明文只存在于 chrome.storage.session(浏览器关闭即清除),10 分钟无操作自动锁定
  • 导出 / 导入支持文件口令加密,兼容 v1 / v2 / v3 三种历史格式
  • 内置口令强度与暴力破解耗时估算
  • 脚本注入范围收敛:只注入用户配置过的域名,未配置的站点不执行任何扩展脚本

其他

  • 中英双语界面
  • 侧边栏(Side Panel)形态,可与网页并排使用

安全设计

主口令 ──PBKDF2-SHA256(20万次, 随机盐)──▶ CryptoKey(不可导出)
                                            │
                    ┌───────────────────────┴───────────────────────┐
                    ▼                                               ▼
        AES-GCM 加密 environments                        IndexedDB 存密钥句柄
                    │                                               │
          chrome.storage.local(密文)                  Service Worker 重启后取回句柄解锁
  • 口令不落盘:Service Worker 空闲被回收后,靠 IndexedDB 中的密钥句柄恢复解锁,无需重新输入口令,同时避免了口令被读取
  • 句柄不可导出:crypto.subtle.exportKey() 对句柄会失败,拿到句柄只能"使用"不能"抄走"
  • 锁定即失效:手动锁定或自动锁定会删除会话明文与密钥句柄
  • 默认零站点权限:不声明 host_permissions,站点访问权走 optional_host_permissions,安装时不申请任何网站访问权限
  • 按域名授权:保存配置时才询问一次"允许访问该网站";拒绝也只是该域名不自动填充,手动填充始终可用(靠 activeTab)
  • 注入范围 = 已授权域名:通过 chrome.scripting.registerContentScripts 动态注册,只注册已授权的站点,锁定时自动清空

技术栈

  • TypeScript(strict 全开)+ Manifest V3
  • 构建:esbuild(打包 popup、压缩产物);tsc 仅做类型检查
  • 测试:node:test + jsdom,无运行时依赖

目录结构

├── manifest.json          扩展清单(不含静态 content_scripts)
├── popup.html / popup.css 侧边栏界面
├── src/
│   ├── background.ts      Service Worker:加解密持久化、密钥恢复、注入范围注册、消息路由
│   ├── content.ts         内容脚本:表单探测与填充引擎(按需注入)
│   ├── utils.ts           URL 匹配 / HTML 转义 / match pattern 转换
│   ├── env-store.ts       环境与配置数据层(session 明文)
│   ├── crypto-store.ts    保险库:PBKDF2 + AES-GCM,锁定 / 解锁
│   ├── crypto-file.ts     导入导出文件的加解密
│   ├── key-store.ts       不可导出密钥句柄的 IndexedDB 存取
│   ├── strength.ts        口令强度与破解耗时估算
│   ├── messaging.ts       runtime 消息封装(含重试)
│   ├── i18n.ts            国际化
│   └── popup/             侧边栏各模块(入口 main.ts,通过 PopupCtx 互相调用)
├── scripts/               构建 / 打包 / 发布脚本
├── tests/                 单元与集成测试
├── updates.xml            自托管自更新清单(部署用,不入扩展包)
├── install-policy.reg     Windows 强制安装策略(部署用,不入扩展包)
└── dist/                  构建产物(不入库,需自行构建)

开发

环境要求

Node.js 18+(开发时使用 v24)。

npm install

若 ~/.npm 权限异常导致安装失败,可指定缓存目录:npm install --cache /tmp/npm-cache-autologin

常用命令

命令 说明
npm run typecheck 仅类型检查(tsc --noEmit)
npm run lint ESLint 检查(未使用变量、常见错误)
npm run lint:fix ESLint 自动修复
npm run format Prettier 格式化 src / scripts / tests
npm run format:check 仅检查格式(CI 使用)
npm run build 开发构建,带 sourcemap,输出到 dist/
npm run build:release 发布构建,压缩、无 sourcemap
npm run watch 监听源码变更自动重建
npm test 构建 + 运行全部测试
npm run test:only 只跑测试(需已有 dist/)
npm run package 发布构建 + 打出 release/auto-login-v<版本>.zip
npm run release -- patch 版本递增 + 同步版本号 + 构建打包(见下文)

格式化范围暂定为源码与测试(src / scripts / tests),未包含 popup.html、popup.css 与 _locales,以免产生上千行的纯空白 diff;需要时可自行扩展 package.json 里的 globs。

调试日志

信息类日志(填充过程、注入范围、解锁恢复等)默认静默,避免刷满网页控制台与 Service Worker 控制台。需要排查问题时,在扩展的 Service Worker 控制台执行一次:

chrome.storage.local.set({ debugLog: true });   // 打开
chrome.storage.local.remove("debugLog");        // 关闭

打开后各项日志会以 [AutoLogin] 前缀输出。异常类告警(如注册 content script 失败、填充超时诊断)不受该开关影响,始终输出。

dist/ 不纳入版本控制,克隆后必须先执行 npm run build 才能加载扩展。

本地加载

  1. npm install && npm run build
  2. 打开 chrome://extensions,右上角开启「开发者模式」
  3. 点击「加载已解压的扩展程序」,选择本仓库根目录(即含 manifest.json 的目录)
  4. 点击扩展图标打开侧边栏;首次使用会要求设置本机口令

测试

npm test
  • tests/crypto-store.test.js 保险库加解密、解锁 / 锁定、密钥句柄解锁
  • tests/key-store.test.js 密钥句柄的存取与降级行为
  • tests/permissions.test.js 可选主机权限的授权状态判断与申请
  • tests/env-store.test.js 环境与配置 CRUD
  • tests/utils.test.js URL 匹配、HTML 转义、match pattern 转换、调试日志开关
  • tests/detect-captcha.test.js 验证码识别
  • tests/content-fill.test.js 表单探测与填充引擎(jsdom 真实 DOM,含 Shadow DOM、多环境浮窗、失败次数限制、SPA 重试)

构建与发布

产物分三类,对应不同运行环境(详见 scripts/build.mjs 注释):

  1. 全局脚本(utils / env-store / crypto-store / key-store):UMD,各自独立成文件,浏览器挂 globalThis、Node 测试可直接 require
  2. 独立入口(background / content):不打包,运行期靠 importScripts 与全局变量协作
  3. 模块入口(popup/main):唯一参与打包的入口,ESM,静态依赖全部内联

构建时会校验 manifest.json 与 popup.html 引用的文件是否都存在,并检查版本号是否一致。

发布流程

# 1. 更新 CHANGELOG.md
# 2. 递增版本并打包(同步 manifest.json / package.json / updates.xml)
npm run release -- patch        # 或 minor / major / 1.2.0
# 3. 提交并打标签
git add -A && git commit -m "release: v1.0.1"
git tag v1.0.1 && git push && git push --tags

产物位于 release/auto-login-v<版本>.zip:上传 Chrome Web Store 用该 zip;自托管自更新需用同一份内容打包为 .crx,并更新 updates.xml 的 codebase。

推送 v* 标签会触发 .gitea/workflows/release.yml:安装依赖 → 测试 → 打包 → 上传 zip 产物。

权限说明

权限 用途
storage 保存域名配置(密文存 local)与解锁期间的会话数据
activeTab 你点击扩展图标时临时访问当前标签页,用于「在当前页面填充」与「填入当前域名」
scripting 按需注入填充脚本;注入范围仅限你已授权的域名
sidePanel 提供侧边栏界面
bookmarks 从浏览器书签批量导入域名(仅在你点击「从书签导入」时读取)
optional_host_permissions: *://*/* 仅为"可申请"声明,安装时不授予。你在保存某个域名配置时会被询问一次是否允许访问该网站;未授权的站点不会注入任何脚本

注入粒度是"已授权域名下的所有帧"(allFrames):iframe 里的登录表单也能被填充,因此同一域名下嵌的第三方 iframe 也会执行脚本;但每个帧都会用自己的地址去匹配配置,不匹配的帧不做任何操作。

未声明 host_permissions,也未声明 tabs,因此安装提示中不会出现"读取和更改您在所有网站上的数据"或"读取您的浏览记录"。

撤销授权:在 chrome://extensions 的扩展详情页中移除对应站点权限即可,扩展会立即同步注销注入范围(该域名退化为只能手动填充)。

隐私

不收集、不上传任何数据。数据处理方式详见 PRIVACY.md。

许可证

MIT

S
Description
匹配域名,自动填充用户名密码并自动登录
Readme MIT
5.4 MiB
Languages
TypeScript 48.9%
JavaScript 27.3%
HTML 16.9%
CSS 6.9%