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.

signup-login

邮箱注册 / 登录 + 6 位验证码校验。Hono JSX 服务端渲染,SQLite 存数据,零第三方依赖。

打开应用

流程

Rendering mermaid diagram...

文件

文件作用
index.tsx路由 + 页面(/signup/verify/login/logout
db.ts三张表(users / login_codes / sessions)和所有查询
auth.tsPBKDF2 密码哈希、验证码、会话 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, and bcc blank.

所以现在这个版本:注册、验证码生成、验证、登录全都正常,只有"把邮件投递给真实用户"这一步会失败,页面上会明确提示。

两个出路:

  1. 升级 Pro —— 不用改任何代码,mail.ts 照旧。
  2. 换成自己的邮件服务 —— 改 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 文件即可)