0

0

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

霞舞

霞舞

发布时间:2026-01-06 18:45:02

|

223人浏览过

|

来源于php中文网

原创

如何在静态托管网站中安全集成 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 字段):

Vozo
Vozo

Vozo是一款强大的AI视频编辑工具,可以帮助用户轻松重写、配音和编辑视频。

下载
// 在 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(权限仅限调用上述两个函数),替换前端密钥:

<script src="https://unpkg.com/faunadb@4.0.0/dist/faunadb.js"></script>
<script>
  // ✅ 使用 Public Key(无写权限!)
  const client = new faunadb.Client({
    secret: "fnAPU...your_public_key..." // 替换为 Fauna 控制台生成的 public key
  });

  async function signUp() {
    const email = document.getElementById("email").value;
    const password = document.getElementById("password").value;
    try {
      await client.query(
        q.Call(q.Function("signup"), [email, password])
      );
      alert("Sign up successful! Check your email.");
    } catch (e) {
      console.error("Signup failed:", e);
      alert("Invalid email or password.");
    }
  }

  async function login() {
    const email = document.getElementById("email").value;
    const password = document.getElementById("password").value;
    try {
      const { secret } = await client.query(
        q.Call(q.Function("login"), [email, password])
      );
      // ✅ 获取用户专属 Token(含受限权限)
      const userClient = new faunadb.Client({ secret });
      alert("Login successful!");
      // 后续请求使用 userClient(例如读取个人资料)
    } catch (e) {
      console.error("Login failed:", e);
      alert("Incorrect email or password.");
    }
  }
</script>

⚠️ 关键注意事项

  • 永不暴露管理密钥(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 官方认证教程 实践部署。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6583

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

841

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1091

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

2096

2024.03.01

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

548

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

30

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

44

2026.01.06

点击input框没有光标怎么办
点击input框没有光标怎么办

点击input框没有光标的解决办法:1、确认输入框焦点;2、清除浏览器缓存;3、更新浏览器;4、使用JavaScript;5、检查硬件设备;6、检查输入框属性;7、调试JavaScript代码;8、检查页面其他元素;9、考虑浏览器兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

197

2023.11.24

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

4

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 5.9万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号