如何在静态托管网站中安全集成 Fauna 数据库实现用户认证

本文详解在静态网站(如 github pages、vercel)中安全使用 fauna 实现用户注册与登录,重点解决前端直连导致的权限泄露风险,推荐采用 udf + 凭据(credentials)+ 令牌(token)的标准化认证模式。

在静态托管站点中直接将 Fauna 秘钥(secret)硬编码于前端 JavaScript 中——如你当前代码所示——存在严重安全隐患:该密钥一旦泄露,攻击者即可完全控制你的数据库,执行任意读写操作。更危险的是,你当前的 login() 函数直接通过 q.Get(q.Match(...)) 获取完整用户文档,并用明文比对 result.password,而实际数据结构中密码位于 result.data.password(因 Fauna 文档的业务数据始终嵌套在 data 字段下)。这不仅逻辑错误,更暴露了原始密码字段,违背最小权限与安全存储原则。

✅ 正确做法是:禁用前端直连管理密钥,改用 Fauna 原生 Credentials 机制 + 自定义函数(UDF)封装认证逻辑。以下是关键改进步骤:

1. 启用 Credentials 并创建安全索引

在 Fauna Dashboard 中为 users 集合启用凭据支持(无需手动存 password 字段):

// 在 Shell 中执行(需管理员密钥)
CreateCollection({ name: "users" })

// 启用 Credentials(自动哈希密码,仅存 salted hash)
CreateCredentials({ 
  collection: Collection("users") 
})

// 创建唯一邮箱索引(用于查找用户)
CreateIndex({
  name: "users_by_email",
  source: Collection("users"),
  terms: [{ field: ["data", "email"] }],
  unique: true
})

2. 编写安全 UDF(Signup & Login)

在 Fauna 中创建两个函数,仅允许公共密钥调用

// Function: signup
Query(
  Lambda(
    ["email", "password"],
    Let(
      {
        user: Create(Collection("users"), {
          credentials: { password: Var("password") },
          data: { email: Var("email") }
        })
      },
      Var("user")
    )
  )
)
// Function: login  
Query(
  Lambda(
    ["email", "password"],
    Let(
      {
        userRef: Select(
          ["ref"],
          Get(Match(Index("users_by_email"), Var("email")))
        ),
        loginResult: Login(Var("userRef"), { password: Var("password") })
      },
      Var("loginResult")
    )
  )
)

3. 前端调用 UDF(使用 Public Key)

生成一个 Public Key(权限仅限调用上述两个函数),替换前端密钥:

⚠️ 关键注意事项

  • 永不暴露管理密钥(Admin Secret)到前端:它应只用于服务端或 CI/CD 初始化。
  • Credentials 是必须的:Fauna 的 Login() 函数依赖凭据集合,明文存密码是反模式。
  • Token 权限可控:Login() 返回的 secret 可绑定 Role,限制用户仅能访问自身数据(例如 Read(Collection("posts")) 且 Where("author", Identity()))。
  • HTML ID 冲突修复:你的表单中两个 input#email 和 input#password ID 重复,会导致 document.getElementById 获取错误元素。请为登录/注册表单分别使用唯一 ID(如 id="signup-email" / id="login-email")。

遵循此方案,你的静态网站即可获得企业级认证能力:密码零明文传输、权限严格隔离、密钥永不泄露。立即参考 Fauna 官方认证教程 实践部署。