Public
邮箱注册 + 登录 + 验证码校验,SQLite 存用户,Hono JSX 页面
emailsqliteweb
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
邮箱注册 / 登录 + 6 位验证码校验。Hono JSX 服务端渲染,SQLite 存数据,零第三方依赖。
Rendering mermaid diagram...
| 文件 | 作用 |
|---|---|
index.tsx | 路由 + 页面(/signup、/verify、/login、/logout) |
db.ts | 三张表(users / login_codes / sessions)和所有查询 |
auth.ts | PBKDF2 密码哈希、验证码、会话 token、cookie 读写 |
mail.ts | 发验证码邮件 |
test.ts | 单元测试,用 run_file 直接跑 |
跑测试:
run_file("drmy01bsp6bi/signup-login", "test.ts")
- 密码用 PBKDF2-SHA256,10 万次迭代,每个用户独立随机盐。
- 验证码和会话 token 都只存 SHA-256 哈希。数据库泄露也拿不到能直接用的凭证。
- 会话 cookie 带
HttpOnly+Secure+SameSite=Lax,30 天过期。 - 登录失败统一提示"邮箱或密码不对";邮箱不存在时也照样跑一遍哈希校验,避免用响应时间判断邮箱是否注册过。
- 验证码:10 分钟过期、用掉即失效、错 5 次作废、30 秒冷却、每小时最多 5 次。
- 页面只渲染文案代码(
?err=bad_code),用户输入不会被反射回页面。
std/email 在免费账号上只能发给本账号自己的邮箱,日志原文:
Free tier users can only send email to themselves — leave
to,cc, andbccblank.
所以现在这个版本:注册、验证码生成、验证、登录全都正常,只有"把邮件投递给真实用户"这一步会失败,页面上会明确提示。
两个出路:
- 升级 Pro —— 不用改任何代码,
mail.ts照旧。 - 换成自己的邮件服务 —— 改
mail.ts里的发送实现(比如 Resend),把 API key 放进环境变量。
👉 Add RESEND_API_KEY here: https://www.val.town/x/drmy01bsp6bi/signup-login/environment-variables?key=RESEND_API_KEY
另外,邮件发送失败时验证码会打到日志里([dev] ... 的验证码是 ...),方便你自己跑通流程。正式上线前把 index.tsx 里那行 console.log 删掉。
- 忘记密码 / 重置密码
- 改密码、改邮箱、注销账号
- 会话管理(列出登录设备、"退出所有设备")
- CSRF token —— 目前靠
SameSite=Lax+ 表单 POST 兜底,够用但不是零风险 - 清理过期会话和验证码的定时任务(加一个 interval 文件即可)