04Java · Spring Boot · SQLiteJava · Spring Boot · SQLite
accc-Libra
A Spring Boot web app: a captcha-verified public page, a password-protected admin page with single entry and CSV batch import, and SQLite storage created on startup.一个 Spring Boot Web 应用:带人机验证的公开页、有口令保护的管理页(单条录入和 CSV 批量导入),以及启动时自动建表的 SQLite 存储。
# application.yaml — every secret can be overridden
spring.datasource.url: jdbc:sqlite:app.db
spring.sql.init.mode: always # schema on start
captcha.id: ${CAPTCHA_ID}
captcha.key: ${CAPTCHA_KEY}
admin.token: ${ADMIN_TOKEN}01The problem问题
A small service that has to be safe by default.一个小服务,也得默认安全。
Bots on the public page公开页上的机器人
A public endpoint that hands out records must make sure a person, not a script, is asking.对外提供记录的公开接口,必须确认是人在请求,而不是脚本。
Bulk data entry批量录入
The admin needs to add one record quickly, or hundreds from a spreadsheet, without breaking existing data.管理员既要能快速加一条,也要能从表格一次导入几百条,而且不能破坏已有数据。
Zero setup零配置部署
It should run from one jar with no database server to install.应该一个 jar 就能跑,不需要另装数据库服务。
02What I built我做了什么
Spring Boot, SQLite, and a captcha gate.Spring Boot、SQLite 和一道人机验证。
A Spring Boot app with two pages: a public page gated by Geetest v4 captcha verification on the server, and a password-protected admin page. SQLite holds the data, and the schema is created on startup.一个有两个页面的 Spring Boot 应用:公开页由服务端校验 Geetest v4 人机验证,管理页有口令保护。数据存在 SQLite,启动时自动建表。
- Server-side captcha check: the page sends the challenge result; the server verifies it with the provider before doing anything.服务端校验人机验证:页面提交验证结果,服务端先向验证服务确认,再做任何操作。
- Admin page with single entry and CSV batch import, validated row by row.管理页支持单条录入和 CSV 批量导入,逐行校验。
- Every secret can be overridden by an environment variable, so nothing sensitive needs to live in the repo.所有密钥都能用环境变量覆盖,敏感信息不需要放进仓库。
- 51 JUnit test classes, plus Python tooling with its own tests.51 个 JUnit 测试类,另有带测试的 Python 工具。
03How it works怎么做的
Two doors into one database.两扇门,通向同一个数据库。
- STEP 01
Public page公开页
Static HTML + JS, captcha widget.静态 HTML + JS,人机验证组件。
- STEP 02
Captcha verify人机验证
Server checks the token with Geetest v4.服务端向 Geetest v4 校验令牌。
- STEP 03
Spring serviceSpring 服务
Controllers, validation, transactions.控制器、校验、事务。
- STEP 04
SQLiteSQLite
One file; schema created on start.一个文件;启动时建表。
- STEP 05
Admin page管理页
Token-protected; single entry or CSV import.口令保护;单条录入或 CSV 导入。
05Tech used用到的技术
What it’s made of.用什么做的。
- Server服务端
- Java 17
- Spring Boot
- Maven
- Data数据
- SQLite
- JDBC
- CSV
- Security安全
- Geetest v4
- env overrides环境变量覆盖
- token-protected admin口令保护的管理页
- Quality质量
- 51 JUnit test classes51 个 JUnit 测试类
- Private repository私有仓库
06What I learned我学到了什么
Lessons I’ll keep.会一直记得的几件事。
- Never trust the browser. The captcha result is only a claim until the server verifies it; the first version learned this the hard way in testing.永远别信浏览器。人机验证的结果在服务端确认之前只是一个说法;第一版在测试里吃过这个亏。
- Imports need a dry run. Validating every CSV row before writing any made bulk import boring, which is what you want.导入要先试跑。先校验 CSV 的每一行、再写入任何一条,批量导入就变得很无聊,这正是想要的。
- The simplest database that works. SQLite meant one file to back up and no server to run.用够用的最简单数据库。SQLite 意味着只需要备份一个文件,也不用运行数据库服务。