Authelia 构建与测试完全指南:从源码构建、单元测试到集成测试套件
【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia
Authelia是一个基于 React 前端门户与 Go 后端 API 组合而成的开源单点登录(SSO)多因素认证(MFA)项目。对开发者而言,从源码构建、运行单元测试、再到在完整的生态系统中跑集成测试,是一套完整且体系化的流程。本文以官方贡献指南 build-and-test.md 为核心,结合仓库内的 authelia-scripts 源码与 integration-suites.md 文档,完整讲解 Authelia 的构建与测试方法,读完后你将掌握:如何加载开发环境、如何用 Suites 从源码热重载运行 Authelia、如何执行单元测试与集成测试,以及如何手动构建发布级二进制。
架构概览:一个 Go 壳里的 React 门户
Authelia的产物形态非常清晰:一个 React 编写的前端用户门户,被打包进一个 Go 应用里;这个 Go 应用同时充当静态资源 Web 服务器和专用 API 服务。因此,任何一次构建都必须同时处理两部分:
- 前端:位于仓库根目录的 web 目录,使用 pnpm 管理依赖并产出静态资源;
- 后端:位于 cmd/authelia 的 Go 入口,负责把前端资源嵌入二进制并提供 API。
仓库为开发者提供了一整套专用的 CLI 工具 ——authelia-scripts,它被封装在 cmd/authelia-scripts 目录下。从其根命令的定义(root.go)可以看到,它聚合了bootstrap、build、clean、ci、docker、serve、suites、unittest、xflags等子命令,覆盖了"构建二进制、构建 Docker 镜像、搭建集成测试套件、执行测试"等全部开发任务。它的自述(const.go)也明确说明:该工具既服务于开发者手动操作,也被 CI/CD 流水线用于自动化单元测试与集成测试。
开发前置:准备环境并加载开发上下文
在动手构建与贡献之前,必须先完成 Environment 指南中的环境配置。Authelia 官方推荐在 Linux 上进行开发,其核心前置条件如下:
| 类别 | 依赖 | 版本要求 |
|---|---|---|
| 通用 | git、bash | 现代 Linux 发行版;Windows 与 macOS 非官方支持 |
| 后端 | go | 最低 v1.24.3;以 go.mod 中声明的 toolchain 为准(当前仓库为go 1.26.0、toolchain go1.27.1) |
| 后端 | gcc、gomock | — |
| 前端 | Node.js | v22.15.0 或更高 |
| 前端 | pnpm | v10.10.0 或更高 |
| 集成测试 | Docker / Docker Compose | v28.1.1+ / v2.36.0+,且必须以系统包方式安装(不支持 Snappy 等工具) |
| 集成测试 | chromium、delve | 用于 Selenium 驱动的浏览器测试与远程调试 |
环境就绪后,在仓库根目录执行以下命令即可加载Authelia 开发上下文:
source bootstrap.shbootstrap.sh 会做几件事:把cmd/dev/、.buildkite/steps/、web/node_modules/.bin等目录加入PATH(其中 cmd/dev/authelia-scripts 是一个用go run包装 authelia-scripts 的脚本),自动设置USER_ID/GROUP_ID,并在非 CI 环境下为当前工作树分配一个suite slot(详见后文"并发运行套件"),最后自动执行authelia-scripts bootstrap。加载后你就拥有以下命令:
authelia-scripts—— 执行构建、建 Docker 镜像、搭建套件、跑测试等开发任务;authelia-gen—— 执行代码生成,官方建议每次改代码后、提交前运行;authelia-suites—— 套件管理工具(一般推荐用 authelia-scripts 代替)。
快速开始:用 Suites 从源码运行 Authelia
为了降低开发门槛,Authelia 引入了Suites(套件)概念:它是一套"虚拟环境 + 测试集合",通过 Docker Compose 拉起一个完整的生态(LDAP、Redis、SQL 服务器、反向代理等),并让 Authelia 以源码形式在其中运行。关键特性是Authelia 在该环境中会被热重载(hot-reload),你改完代码后补丁会立刻生效,方便边改边观察。
启动名为Standalone的套件:
authelia-scripts suites setup Standalone绝大多数套件使用 Docker Compose 拉起环境,因此可以用 Docker 原生命令查看某个组件的日志,例如查看 Authelia 后端容器:
docker logs authelia-authelia-backend-1 -f之后即可编辑代码,并观察 Authelia 如何被自动重新加载。
套件环境的访问方式
按 integration-suites.md 的说明,本地开发套件有标准化的网络布局:
- 后端(Authelia 二进制容器):
192.168.240.50 - 前端(承载各 Web 应用的服务器):
192.168.240.100
所有站点都托管在${SUITE_SUBNET}.100:8080上,即本地默认的192.168.240.100:8080。常用站点包括 Authelia(login.example.com:8080)、Mailpit(mail.example.com:8080)、OIDC 测试应用、Duo、Traefik/HAProxy 面板,以及public/singlefactor/secure/admin/deny.example.com等一系列简单测试应用。完整的 host 条目定义可查看 internal/suites/hosts.go。
单元测试
运行整个后端的单元测试只需一条命令:
authelia-scripts unittest从 unittest.go 的源码可以看到该命令的真实行为:它先执行
go test -coverprofile=coverage.txt -covermode=atomic $(go list ./... | grep -v suites)即对除internal/suites(集成测试)以外的所有 Go 包运行带覆盖率统计的测试;随后切换到 web 目录执行pnpm test(并注入CI=true环境变量),覆盖前端单测。也就是说,authelia-scripts unittest会同时验证后端 Go 单测与前端 pnpm 单测两部分。若在 CI(Buildkite)中运行,还会附加-race竞态检测标志(通过--buildkite全局参数开启,见 root.go)。
集成测试:基于 Selenium 的 Suites
集成测试位于 internal/suites 目录下,基于 Selenium(chromedriver)驱动真实浏览器执行。一个suite是"环境 + 测试"的组合:执行套件意味着依次完成"启动环境 → 运行测试 → 拆除环境"。每一步都可以独立执行。
列出可用套件
authelia-scripts suites list输出示例:
Standalone DuoPush LDAP Traefik实际上,仓库在 internal/suites 下提供了远不止这些套件,包括 ActiveDirectory、BypassAll、Caddy、Envoy、HAProxy、HighAvailability、Kubernetes、MariaDB、MySQL、OIDC、PAM、Postgres、TwoFactor 等 20 余个场景。suites.go 显示list命令直接读取suites.GlobalRegistry注册表并按名称排序输出。
分步执行:setup / test / teardown
启动 Standalone 套件环境:
authelia-scripts suites setup Standalone对当前正在运行的套件执行测试:
authelia-scripts suites test拆除当前运行套件的环境:
authelia-scripts suites teardown Standalone在 suites.go 中可以看到setup内部逻辑:它会校验套件存在(checkSuiteAvailable)、通过go run cmd/authelia-suites/main.go setup <suite>启动 Compose 环境,并监听SIGINT/SIGTERM;一旦超时(ErrTimeoutReached)或被打断,会自动回滚执行 teardown,保证环境不会残留。
一次命令跑完整个套件
如果当前没有运行任何套件,也可以直接用一条命令完成"起环境 → 跑测试 → 拆环境"全流程,例如测试Standalone套件:
authelia-scripts suites test Standalone若要一次性测试所有套件(官方提示大约需要 30 分钟),确保当前没有运行中的套件,然后执行:
authelia-scripts suites test不带参数的test命令会遍历GlobalRegistry中全部套件依次执行(见 suites.go 的runAllSuites)。
源码级解析:suites test 究竟做了什么
深入 suites.go 的runSuiteTests,可以看到测试执行的真实机制:
- 若传入套件名且当前无运行中套件,先自动
setupSuite; - 根据套件定义的
TestTimeout(默认 60 秒)构造超时参数; - 组装一条真实的
go test命令:
go test -count=1 -v -json ./internal/suites -timeout 60s -run '^(TestStandaloneSuite)$'- 支持三个可选参数(suites.go):
--failfast:首个测试失败即停止;--headless:以无头模式运行浏览器测试(内部通过注入HEADLESS=y环境变量实现);--test <pattern>:仅运行匹配指定正则的单个测试。
- 测试输出会同时写入
test-results-<suite>.json结果文件; - 测试失败时会回调套件的
OnError钩子(如收集现场截图),最后按需 teardown。
另外,当前正在运行的套件名称会被记录在仓库根目录的.suite文件中(suites.go),test/teardown命令据此判断"当前运行的是哪个套件",这也是"不带参数跑测试"能命中正确套件的原因。
手动构建 Authelia
如果不想借助套件环境,也可以完全手动地从源码构建二进制。前提是先按 Environment 的 Setup 一节配置好开发环境,以下步骤以 Linux 为例(其他系统需适当调整)。
1. 克隆仓库
git clone https://gitcode.com/GitHub_Trending/au/authelia.git2. 下载依赖
cd authelia && go mod download cd web && pnpm install cd ..go mod download拉取 Go 模块依赖;前端依赖则进入 web 目录用 pnpm 安装。
3. 构建 Web 前端
cd web && pnpm build cd .. cp -r api internal/server/public_html/api前端构建产物生成后,需要把 api 目录(含 OpenAPI 定义等)复制到 internal/server/public_html/api,由 Go 内嵌静态资源服务一并托管。
4. 构建二进制(保留调试符号)
CGO_ENABLED=1 CGO_CPPFLAGS="-D_FORTIFY_SOURCE=2 -fstack-protector-strong" CGO_LDFLAGS="-Wl,-z,relro,-z,now" \ go build -ldflags "-linkmode=external" -trimpath -buildmode=pie -o authelia ./cmd/authelia5. 构建二进制(去除调试符号,体积更小)
CGO_ENABLED=1 CGO_CPPFLAGS="-D_FORTIFY_SOURCE=2 -fstack-protector-strong" CGO_LDFLAGS="-Wl,-z,relro,-z,now" \ go build -ldflags "-linkmode=external -s -w" -trimpath -buildmode=pie -o authelia ./cmd/authelia这些构建参数的含义与作用如下:
| 参数 | 作用 |
|---|---|
CGO_ENABLED=1 | 启用 CGO,使二进制能链接系统库(如 LDAP、PAM 等原生依赖) |
CGO_CPPFLAGS="-D_FORTIFY_SOURCE=2 -fstack-protector-strong" | 启用 GCC 的缓冲区溢出防护与栈保护 |
CGO_LDFLAGS="-Wl,-z,relro,-z,now" | 开启 RELRO 与立即绑定(BIND_NOW),加固二进制 |
-ldflags "-linkmode=external" | 使用外部链接器,配合加固参数使用 |
-ldflags "-s -w" | 去掉符号表与 DWARF 调试信息(仅无调试符号版本) |
-trimpath | 去除构建路径信息,保证可复现构建 |
-buildmode=pie | 生成位置无关可执行文件(ASLR 友好) |
-o authelia | 输出到当前目录的authelia文件 |
./cmd/authelia | 主程序入口包 |
构建完成后,./authelia即为可运行的 Authelia 二进制,配合 config.template.yml 即可启动。
进阶:并发套件、远程调试与扩展套件
并发运行多个套件
在同一台机器上,多个 Git 工作树可以各自运行套件而互不冲突。source bootstrap.sh时会为当前工作树自动分配一个suite slot,并据此派生出所有易冲突的配置(见 bootstrap.sh):
| 派生变量 | 规则 |
|---|---|
COMPOSE_PROJECT_NAME | authelia-${SUITE_SLOT} |
SUITE_SUBNET | 10.240.${SUITE_SLOT} |
LDAP_ADMIN_PORT | 9090 + SUITE_SLOT |
ENVOY_ADMIN_PORT | 9901 + SUITE_SLOT |
SUITE_TMP | /tmp/authelia-suite-${SUITE_SLOT} |
slot 按工作树记忆(每次 source 保持一致),工作树删除后自动释放。可用以下命令查看或管理分配:
authelia-scripts suites slot --list authelia-scripts suites slot --release有 slot 的 shell 会刻意不修改/etc/hosts:测试中的 Chrome 通过--host-resolver-rules、Go 客户端通过拨号解析套件域名,两者共用 internal/suites/hosts.go 中的同一张域名表。因此无 slot 的工作树仍可通过默认192.168.240.0/24网段的地址浏览,而带 slot 的套件地址形如https://10.240.2.100:8080。需要注意的是,pnpm store、Go 模块与构建缓存是共享的(并发安全但会争用),且每个 dev 模式套件大约占用 6 个 CPU 与 6GB 内存,请据此规划并发规模。
远程调试
套件中的 Authelia 通过 delve 运行并支持远程调试,调试端口为${SUITE_SUBNET}.50:2345,即本地默认192.168.240.50:2345。连接示例:
dlv connect 192.168.240.50:2345创建新套件
创建一个套件通常只需三个部分(以 Standalone 为例):
- internal/suites/suite_standalone.go —— 定义 setup/teardown 阶段(通常借助 docker compose 拉起生态)与超时时间;
- internal/suites/suite_standalone_test.go —— 定义针对该套件的测试集合;
- internal/suites/Standalone 目录 —— 存放套件所需资源(通常挂载进容器)。
套件也可以非常复杂,例如仓库中还存在搭建完整 Kubernetes 生态的套件可供参考。测试场景本身则在 internal/suites 下的scenario_*.go文件中实现(如单因子、双因子、OIDC、密码复杂度等场景)。
常见问题
Q:能在 Windows 或 macOS 下开发吗?目前官方不支持,套件在 Windows/macOS 下很难运行,官方推荐使用 Linux。部分维护者个人使用其他系统,但不在官方支持范围内。
Q:为什么不能用旧版 Docker / Docker Compose?仓库中的全部示例与套件都基于现代版本编写,使用旧版本将得不到支持。
Q:套件测试应用托管在任意域名上,如何解析?authelia-scripts bootstrap子命令会自动创建相关 hosts 条目,该步骤在source bootstrap.sh时自动执行。
【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考